diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 9ffbb5ffb6bcea749a5e84e21a12705fe6b85831..7e186303e511bb599da28ef722a36fc9bd053353 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,20 +1,20 @@ -**Change Description** +## Change Description -**Consensus Changes** +## Consensus Changes -**API Changes** +## API Changes -**Documentation Additions** +## Documentation Additions diff --git a/CMakeLists.txt b/CMakeLists.txt index 360d6c973ab322cebe830518377c60faf1c1b541..0fcaeecc03318414f2cebfdbfcb60902e6b7df4e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,8 +34,8 @@ set( CMAKE_CXX_EXTENSIONS ON ) set( CXX_STANDARD_REQUIRED ON) set(VERSION_MAJOR 1) -set(VERSION_MINOR 4) -set(VERSION_PATCH 4) +set(VERSION_MINOR 5) +set(VERSION_PATCH 0-rc1) set( CLI_CLIENT_EXECUTABLE_NAME cleos ) set( NODE_EXECUTABLE_NAME nodeos ) diff --git a/CMakeModules/EosioTester.cmake.in b/CMakeModules/EosioTester.cmake.in index 741ee5f0e846c835180b7b61bc728be11fc542fa..ac2bc0221fa106ef2bab9512972d39aa9ade5cfc 100644 --- a/CMakeModules/EosioTester.cmake.in +++ b/CMakeModules/EosioTester.cmake.in @@ -97,8 +97,8 @@ macro(add_eosio_test test_name) ${liblogging} ${libchainbase} ${libbuiltins} - ${GMP_LIBRARIES} ${libsecp256k1} + ${GMP_LIBRARIES} LLVMX86Disassembler LLVMX86AsmParser diff --git a/CMakeModules/EosioTesterBuild.cmake.in b/CMakeModules/EosioTesterBuild.cmake.in index 04ac7da6fe5948f071757e09f6ee340cf69a4978..7050cda3a0661b557057bcb31cfb29e5cf3702a8 100644 --- a/CMakeModules/EosioTesterBuild.cmake.in +++ b/CMakeModules/EosioTesterBuild.cmake.in @@ -98,8 +98,8 @@ macro(add_eosio_test test_name) ${liblogging} ${libchainbase} ${libbuiltins} - ${GMP_LIBRARIES} ${libsecp256k1} + ${GMP_LIBRARIES} LLVMX86Disassembler LLVMX86AsmParser diff --git a/Docker/Dockerfile b/Docker/Dockerfile index 24dd447ed758653c0fb5dd37d7715bff768080af..ea21477cc51ee595d1ef64bbd45e2ab1d4833d45 100644 --- a/Docker/Dockerfile +++ b/Docker/Dockerfile @@ -6,7 +6,7 @@ RUN git clone -b $branch https://github.com/EOSIO/eos.git --recursive \ && cd eos && echo "$branch:$(git rev-parse HEAD)" > /etc/eosio-version \ && cmake -H. -B"/tmp/build" -GNinja -DCMAKE_BUILD_TYPE=Release -DWASM_ROOT=/opt/wasm -DCMAKE_CXX_COMPILER=clang++ \ -DCMAKE_C_COMPILER=clang -DCMAKE_INSTALL_PREFIX=/tmp/build -DBUILD_MONGO_DB_PLUGIN=true -DCORE_SYMBOL_NAME=$symbol \ - && cmake --build /tmp/build --target install && rm /tmp/build/bin/eosiocpp + && cmake --build /tmp/build --target install FROM ubuntu:18.04 diff --git a/Docker/README.md b/Docker/README.md index db0340e31163b8e141da9ada9b0904cec4f3d23e..ffa178fda9580174e61f5780fbcf059ac13fd40a 100644 --- a/Docker/README.md +++ b/Docker/README.md @@ -20,10 +20,10 @@ cd eos/Docker docker build . -t eosio/eos ``` -The above will build off the most recent commit to the master branch by default. If you would like to target a specific branch/tag, you may use a build argument. For example, if you wished to generate a docker image based off of the v1.4.4 tag, you could do the following: +The above will build off the most recent commit to the master branch by default. If you would like to target a specific branch/tag, you may use a build argument. For example, if you wished to generate a docker image based off of the v1.5.0-rc1 tag, you could do the following: ```bash -docker build -t eosio/eos:v1.4.4 --build-arg branch=v1.4.4 . +docker build -t eosio/eos:v1.5.0-rc1 --build-arg branch=v1.5.0-rc1 . ``` By default, the symbol in eosio.system is set to SYS. You can override this using the symbol argument while building the docker image. diff --git a/README.md b/README.md index 2a048d5b973d316e4e959b2b15e7806358b5d60f..5a933f530a85f7af8e9c145d79bafdd9b8621bec 100644 --- a/README.md +++ b/README.md @@ -39,13 +39,13 @@ $ brew remove eosio ``` #### Ubuntu 18.04 Debian Package Install ```sh -$ wget https://github.com/eosio/eos/releases/download/v1.4.4/eosio_1.4.4-1-ubuntu-18.04_amd64.deb -$ sudo apt install ./eosio_1.4.4-1-ubuntu-18.04_amd64.deb +$ wget https://github.com/eosio/eos/releases/download/v1.5.0-rc1/eosio_1.5.0-rc1-1-ubuntu-18.04_amd64.deb +$ sudo apt install ./eosio_1.5.0-rc1-1-ubuntu-18.04_amd64.deb ``` #### Ubuntu 16.04 Debian Package Install ```sh -$ wget https://github.com/eosio/eos/releases/download/v1.4.4/eosio_1.4.4-1-ubuntu-16.04_amd64.deb -$ sudo apt install ./eosio_1.4.4-1-ubuntu-16.04_amd64.deb +$ wget https://github.com/eosio/eos/releases/download/v1.5.0-rc1/eosio_1.5.0-rc1-1-ubuntu-16.04_amd64.deb +$ sudo apt install ./eosio_1.5.0-rc1-1-ubuntu-16.04_amd64.deb ``` #### Debian Package Uninstall ```sh @@ -53,8 +53,8 @@ $ sudo apt remove eosio ``` #### Centos RPM Package Install ```sh -$ wget https://github.com/eosio/eos/releases/download/v1.4.4/eosio-1.4.4-1.el7.x86_64.rpm -$ sudo yum install ./eosio-1.4.4-1.el7.x86_64.rpm +$ wget https://github.com/eosio/eos/releases/download/v1.5.0-rc1/eosio-1.5.0-rc1-1.el7.x86_64.rpm +$ sudo yum install ./eosio-1.5.0-rc1-1.el7.x86_64.rpm ``` #### Centos RPM Package Uninstall ```sh @@ -62,8 +62,8 @@ $ sudo yum remove eosio.cdt ``` #### Fedora RPM Package Install ```sh -$ wget https://github.com/eosio/eos/releases/download/v1.4.4/eosio-1.4.4-1.fc27.x86_64.rpm -$ sudo yum install ./eosio-1.4.4-1.fc27.x86_64.rpm +$ wget https://github.com/eosio/eos/releases/download/v1.5.0-rc1/eosio-1.5.0-rc1-1.fc27.x86_64.rpm +$ sudo yum install ./eosio-1.5.0-rc1-1.fc27.x86_64.rpm ``` #### Fedora RPM Package Uninstall ```sh diff --git a/contracts/CMakeLists.txt b/contracts/CMakeLists.txt index bd84d155e8552844e7400df9f7a1a6ce73a1d84b..443330c886a307053ccadc97ae65fc37e1803ab3 100644 --- a/contracts/CMakeLists.txt +++ b/contracts/CMakeLists.txt @@ -7,7 +7,6 @@ set(STANDARD_INCLUDE_FOLDERS ${CMAKE_SOURCE_DIR}/contracts ${CMAKE_BINARY_DIR}/c add_subdirectory(eosiolib) add_subdirectory(musl) add_subdirectory(libc++) -add_subdirectory(simple.token) add_subdirectory(eosio.token) add_subdirectory(eosio.msig) add_subdirectory(eosio.sudo) @@ -18,17 +17,14 @@ add_subdirectory(identity) add_subdirectory(stltest) add_subdirectory(test.inline) -#add_subdirectory(bancor) add_subdirectory(hello) add_subdirectory(asserter) -add_subdirectory(infinite) add_subdirectory(proxy) add_subdirectory(test_api) add_subdirectory(test_api_mem) add_subdirectory(test_api_db) add_subdirectory(test_api_multi_index) add_subdirectory(test_ram_limit) -#add_subdirectory(social) add_subdirectory(eosio.bios) add_subdirectory(noop) add_subdirectory(tic_tac_toe) diff --git a/contracts/bancor/CMakeLists.txt b/contracts/bancor/CMakeLists.txt deleted file mode 100644 index b845361e8f0cd50faf2b3248a090eaca12e1406c..0000000000000000000000000000000000000000 --- a/contracts/bancor/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -file(GLOB ABI_FILES "*.abi") -configure_file("${ABI_FILES}" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY) - -add_wast_executable(TARGET bancor - INCLUDE_FOLDERS "${STANDARD_INCLUDE_FOLDERS}" - LIBRARIES libc libc++ eosiolib - DESTINATION_FOLDER ${CMAKE_CURRENT_BINARY_DIR} -) diff --git a/contracts/bancor/bancor.cpp b/contracts/bancor/bancor.cpp deleted file mode 100644 index 15bc9e802c8a6be318694b8a2589da483906f202..0000000000000000000000000000000000000000 --- a/contracts/bancor/bancor.cpp +++ /dev/null @@ -1,18 +0,0 @@ -/** - * @file - * @copyright defined in eos/LICENSE.txt - */ - -#include - -namespace bancor { - -extern "C" { - - /// The apply method implements the dispatch of events to this contract - void apply( uint64_t r, uint64_t c, uint64_t a ) { - bancor::example_converter::apply( c, a ); - } -} - -} diff --git a/contracts/bancor/bancor.hpp b/contracts/bancor/bancor.hpp deleted file mode 100644 index b6030908b81b2a2592a9fde4ff3c986ef35ca102..0000000000000000000000000000000000000000 --- a/contracts/bancor/bancor.hpp +++ /dev/null @@ -1,22 +0,0 @@ -/** - * @file - * @copyright defined in eos/LICENSE.txt - */ -#pragma once - -#include -#include -#include -#include - -#include -#include - -namespace bancor { - typedef eosio::generic_currency< eosio::token > other_currency; - typedef eosio::generic_currency< eosio::token > relay_currency; - typedef eosio::generic_currency< eosio::token > cur_currency; - - typedef converter example_converter; -} /// bancor - diff --git a/contracts/bancor/converter.hpp b/contracts/bancor/converter.hpp deleted file mode 100644 index 774fc910e32768453536a4e495b55c934985e26d..0000000000000000000000000000000000000000 --- a/contracts/bancor/converter.hpp +++ /dev/null @@ -1,166 +0,0 @@ -#pragma once -namespace bancor { - template - class converter_contract { - public: - typedef ConverterCurrency converter_currency; - typedef FirstCurrency first_currency; - typedef SecondCurrency second_currency; - - - static const account_name converter_account = converter_currency::code; - - struct converter_state { - typename converter_currency::token_type supply; /// total supply held by all users - typename converter_currency::token_type balance; /// supply held by converter in its own balance - }; - - struct converter_args { - eosio::account_name to_currency_account; - eosio::symbol_name to_currency_symbol; - uint64_t min_return_currency; - }; - - - template - struct connector { - typedef CurrencyType currency_type; - typedef typename converter_currency::token_type converter_token_type; - typedef typename currency_type::token_type in_token_type; - - converter_token_type convert_to_converter( in_token_type in, converter_state& state ) { - in_token_type balance = currency_type::get_balance( converter_account ); - - /// balance already changed when transfer executed, get pre-transfer balance - in_token_type previous_balance = balance - in; - - auto init_price = (previous_balance * Base) / (Weight * state.supply); - auto init_out = init_price * in; - - auto out_price = (balance*Base) / (Weight * (state.supply+init_out) ); - auto final_out = out_price * in; - - state.balance += final_out; - state.supply += final_out; - - return final_out; - } - - - in_token_type convert_from_converter( converter_token_type converter_in, converter_state& state ) { - in_token_type to_balance = CurrencyType::get_balance( converter_account ); - - auto init_price = (to_balance * Base) / (Weight * state.supply); - in_token_type init_out = init_price * converter_in; - - state.supply -= converter_in; - state.balance -= converter_in; - - auto out_price = ((to_balance-init_out) * Base) / ( Weight * (state.supply) ); - - return out_price * converter_in; - } - - }; - - - - /** - * This is called when we receive RELAY tokens from user and wish to - * convert to one of the connector currencies. - */ - static void on_convert( const typename converter_currency::transfer& trans, - const converter_args& args, - converter_state& state ) { - - if( args.to_currency_type == first_currency ) { - auto output = first_connector::convert_from_converter( trans.quantity, state ); - save_and_send( trans.from, state, output, args.min_return ); - } - else if( args.to_currency_type == second_currency ) { - auto output = second_connector::convert_from_converter( trans.quantity, state ); - save_and_send( trans.from, state, output, args.min_return ); - } - else { - eosio_assert( false, "invalid to currency" ); - } - } - - - /** - * This is called when the converter receives one of the connector currencies and it - * will send either converter tokens or a different connector currency in response. - */ - template - static void on_convert( const typename ConnectorType::currency_type::transfer& trans, - const converter_args& args, - converter_state& state ) - { - /// convert to converter - auto converter_out = ConnectorType::convert_to_converter( trans.quantity, state ); - - if( args.to_currency_type == converter_currency ) - { - save_and_send( trans.from, state, converter_out, args.min_return ); - } - else - { - auto output = ConnectorType::convert_from_converter( converter_out, state ); - save_and_send( trans.from, state, output, args.min_return ); - } - } - - - /** - * This method factors out the boiler plate for parsing args and loading the - * initial state before dispatching to the proper on_convert case - */ - template - static void start_convert( const typename CurrencyType::transfer_memo& trans ) { - auto args = unpack( trans.memo ); - eosio_assert( args.to_currency_type != trans.quantity.token_type(), "cannot convert to self" ); - - auto state = read_converter_state(); - on_convert( trans, args, state ); - } - - - /** - * converter_account first needs to call the currency handler to perform - * user-to-user transfers of the converter token, then if a transfer is sending - * the token back to the converter contract, it should convert like everything else. - * - * This method should be called from apply( code, action ) for each of the - * transfer types that we support (for each currency) - */ - static void on( const typename converter_currency::transfer_memo& trans ) { - converter_currency::on( trans ); - if( trans.to == converter_account ) { - start_convert( trans ); - } - } - - /** - * All other currencies simply call start_convert if to == converter_account - */ - template - static void on( const typename Currency::transfer_memo& trans ) { - if( trans.to == converter_account ) { - start_convert( trans ); - } else { - eosio_assert( trans.from == converter_account, - "received unexpected notification of transfer" ); - } - } - - static void apply( account_name code, action_name action ) { - if( !dispatch( converter_contract, - converter_currency::transfer, - converter_currency::issue, - first_currency::transfer, - second_currency::transfer ) { - eosio_assert( false, "received unexpected action" ); - } - } - }; /// converter_contract -} /// namespace bancor diff --git a/contracts/bancor/eosio.system.abi b/contracts/bancor/eosio.system.abi deleted file mode 100644 index c8d8e4b16e908bcede68ba02f90bd7d86d7ed391..0000000000000000000000000000000000000000 --- a/contracts/bancor/eosio.system.abi +++ /dev/null @@ -1,37 +0,0 @@ -{ - "types": [{ - "new_type_name": "account_name", - "type": "name" - } - ], - "structs": [{ - "name": "transfer", - "base": "", - "fields": [ - {"name":"from", "type":"account_name"}, - {"name":"to", "type":"account_name"}, - {"name":"quantity", "type":"uint64"} - ] - },{ - "name": "account", - "base": "", - "fields": [ - {"name":"key", "type":"name"}, - {"name":"balance", "type":"uint64"} - ] - } - ], - "actions": [{ - "name": "transfer", - "type": "transfer" - } - ], - "tables": [{ - "name": "account", - "type": "account", - "index_type": "i64", - "key_names" : ["key"], - "key_types" : ["name"] - } - ] -} \ No newline at end of file diff --git a/contracts/eosiolib/currency.hpp b/contracts/eosiolib/currency.hpp deleted file mode 100644 index 1328c493876a829fc52df1d434343194815f3114..0000000000000000000000000000000000000000 --- a/contracts/eosiolib/currency.hpp +++ /dev/null @@ -1,254 +0,0 @@ -#pragma once -#include -#include -#include - -namespace eosio { - using std::string; - using std::array; - - /** - * This contract enables the creation, issuance, and transfering of many different tokens. - * @deprecated This class is deprecated in favor of eosio.token in Dawn 3.0 - */ - class currency { - public: - currency( account_name contract ) - :_contract(contract) - { } - - struct create { - account_name issuer; - asset maximum_supply; - // array issuer_agreement_hash; - uint8_t issuer_can_freeze = true; - uint8_t issuer_can_recall = true; - uint8_t issuer_can_whitelist = true; - - /*(issuer_agreement_hash)*/ - EOSLIB_SERIALIZE( create, (issuer)(maximum_supply)(issuer_can_freeze)(issuer_can_recall)(issuer_can_whitelist) ) - }; - - struct transfer - { - account_name from; - account_name to; - asset quantity; - string memo; - - EOSLIB_SERIALIZE( transfer, (from)(to)(quantity)(memo) ) - }; - - struct issue { - account_name to; - asset quantity; - string memo; - - EOSLIB_SERIALIZE( issue, (to)(quantity)(memo) ) - }; - - struct fee_schedule { - uint64_t primary_key()const { return 0; } - - array fee_per_length; - EOSLIB_SERIALIZE( fee_schedule, (fee_per_length) ) - }; - - struct account { - asset balance; - bool frozen = false; - bool whitelist = true; - - uint64_t primary_key()const { return balance.symbol.name(); } - - EOSLIB_SERIALIZE( account, (balance)(frozen)(whitelist) ) - }; - - struct currency_stats { - asset supply; - asset max_supply; - account_name issuer; - bool can_freeze = true; - bool can_recall = true; - bool can_whitelist = true; - bool is_frozen = false; - bool enforce_whitelist = false; - - uint64_t primary_key()const { return supply.symbol.name(); } - - EOSLIB_SERIALIZE( currency_stats, (supply)(max_supply)(issuer)(can_freeze)(can_recall)(can_whitelist)(is_frozen)(enforce_whitelist) ) - }; - - typedef eosio::multi_index accounts; - typedef eosio::multi_index stats; - - - asset get_balance( account_name owner, symbol_name symbol )const { - accounts t( _contract, owner ); - return t.get(symbol).balance; - } - - asset get_supply( symbol_name symbol )const { - accounts t( _contract, symbol ); - return t.get(symbol).balance; - } - - static void inline_transfer( account_name from, account_name to, extended_asset amount, string memo = string(), permission_name perm = N(active) ) { - action act( permission_level( from, perm ), amount.contract, N(transfer), transfer{from,to,amount,memo} ); - act.send(); - } - - void inline_transfer( account_name from, account_name to, asset amount, string memo = string(), permission_name perm = N(active) ) { - action act( permission_level( from, perm ), _contract, N(transfer), transfer{from,to,amount,memo} ); - act.send(); - } - - - bool apply( account_name contract, action_name act ) { - if( contract != _contract ) - return false; - - switch( act ) { - case N(issue): - print( "issue\n"); - on( unpack_action_data() ); - return true; - case N(transfer): - print( "transfer\n"); - on( unpack_action_data() ); - return true; - case N(create): - print( "create\n"); - on( unpack_action_data() ); - return true; - } - return false; - } - - /** - * This is factored out so it can be used as a building block - */ - void create_currency( const create& c ) { - auto sym = c.maximum_supply.symbol; - eosio_assert( sym.is_valid(), "invalid symbol name" ); - - stats statstable( _contract, sym.name() ); - auto existing = statstable.find( sym.name() ); - eosio_assert( existing == statstable.end(), "token with symbol already exists" ); - - statstable.emplace( c.issuer, [&]( auto& s ) { - s.supply.symbol = c.maximum_supply.symbol; - s.max_supply = c.maximum_supply; - s.issuer = c.issuer; - s.can_freeze = c.issuer_can_freeze; - s.can_recall = c.issuer_can_recall; - s.can_whitelist = c.issuer_can_whitelist; - }); - } - - void issue_currency( const issue& i ) { - auto sym = i.quantity.symbol.name(); - stats statstable( _contract, sym ); - const auto& st = statstable.get( sym ); - - statstable.modify( st, 0, [&]( auto& s ) { - s.supply.amount += i.quantity.amount; - eosio_assert( s.supply.amount >= 0, "underflow" ); - }); - - add_balance( st.issuer, i.quantity, st, st.issuer ); - } - - - void on( const create& c ) { - require_auth( c.issuer ); - create_currency( c ); - - /* - auto fee = get_fee_schedule()[c.maximum_supply.name_length()]; - if( fee.amount > 0 ) { - inline_transfer( c.issuer, _contract, fee, "symbol registration fee" ); - } - */ - } - - void on( const issue& i ) { - auto sym = i.quantity.symbol.name(); - stats statstable( _contract, sym ); - const auto& st = statstable.get( sym ); - - require_auth( st.issuer ); - eosio_assert( i.quantity.is_valid(), "invalid quantity" ); - eosio_assert( i.quantity.amount > 0, "must issue positive quantity" ); - - statstable.modify( st, 0, [&]( auto& s ) { - s.supply.amount += i.quantity.amount; - }); - - add_balance( st.issuer, i.quantity, st, st.issuer ); - - if( i.to != st.issuer ) - { - inline_transfer( st.issuer, i.to, i.quantity, i.memo ); - } - } - - void on( const transfer& t ) { - require_auth(t.from); - auto sym = t.quantity.symbol.name(); - stats statstable( _contract, sym ); - const auto& st = statstable.get( sym ); - - require_recipient( t.to ); - - eosio_assert( t.quantity.is_valid(), "invalid quantity" ); - eosio_assert( t.quantity.amount > 0, "must transfer positive quantity" ); - sub_balance( t.from, t.quantity, st ); - add_balance( t.to, t.quantity, st, t.from ); - } - - - private: - void sub_balance( account_name owner, asset value, const currency_stats& st ) { - accounts from_acnts( _contract, owner ); - - const auto& from = from_acnts.get( value.symbol.name() ); - eosio_assert( from.balance.amount >= value.amount, "overdrawn balance" ); - - if( has_auth( owner ) ) { - eosio_assert( !st.can_freeze || !from.frozen, "account is frozen by issuer" ); - eosio_assert( !st.can_freeze || !st.is_frozen, "all transfers are frozen by issuer" ); - eosio_assert( !st.enforce_whitelist || from.whitelist, "account is not white listed" ); - } else if( has_auth( st.issuer ) ) { - eosio_assert( st.can_recall, "issuer may not recall token" ); - } else { - eosio_assert( false, "insufficient authority" ); - } - - from_acnts.modify( from, owner, [&]( auto& a ) { - a.balance.amount -= value.amount; - }); - } - - void add_balance( account_name owner, asset value, const currency_stats& st, account_name ram_payer ) - { - accounts to_acnts( _contract, owner ); - auto to = to_acnts.find( value.symbol.name() ); - if( to == to_acnts.end() ) { - eosio_assert( !st.enforce_whitelist, "can only transfer to white listed accounts" ); - to_acnts.emplace( ram_payer, [&]( auto& a ){ - a.balance = value; - }); - } else { - eosio_assert( !st.enforce_whitelist || to->whitelist, "receiver requires whitelist by issuer" ); - to_acnts.modify( to, 0, [&]( auto& a ) { - a.balance.amount += value.amount; - }); - } - } - - private: - account_name _contract; - }; - -} diff --git a/contracts/infinite/CMakeLists.txt b/contracts/infinite/CMakeLists.txt deleted file mode 100644 index af3ec44f4967e8b1d65cfea82471b2d68a7f9048..0000000000000000000000000000000000000000 --- a/contracts/infinite/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -add_wast_executable(TARGET infinite - INCLUDE_FOLDERS "${STANDARD_INCLUDE_FOLDERS}" - LIBRARIES libc++ libc eosiolib - DESTINATION_FOLDER ${CMAKE_CURRENT_BINARY_DIR} -) diff --git a/contracts/infinite/infinite.cpp b/contracts/infinite/infinite.cpp deleted file mode 100644 index 21a542c1a282ee9e5aa4584c34f7036667371459..0000000000000000000000000000000000000000 --- a/contracts/infinite/infinite.cpp +++ /dev/null @@ -1,16 +0,0 @@ -/** - * @file - * @copyright defined in eos/LICENSE.txt - */ -#include /// defines transfer struct (abi) - -extern "C" { - - /// The apply method just prints forever - void apply( uint64_t, uint64_t, uint64_t ) { - int idx = 0; - while(true) { - eosio::print(idx++); - } - } -} diff --git a/contracts/simple.token/CMakeLists.txt b/contracts/simple.token/CMakeLists.txt deleted file mode 100644 index 1e755eabe2f49aa2ec424f1b1d4998bb043cfb7b..0000000000000000000000000000000000000000 --- a/contracts/simple.token/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ - -file(GLOB ABI_FILES "*.abi") -configure_file("${ABI_FILES}" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY) - -add_wast_executable(TARGET simple.token - INCLUDE_FOLDERS "${STANDARD_INCLUDE_FOLDERS}" - LIBRARIES libc++ libc eosiolib - DESTINATION_FOLDER ${CMAKE_CURRENT_BINARY_DIR} -) diff --git a/contracts/simple.token/simple.token.abi b/contracts/simple.token/simple.token.abi deleted file mode 100644 index 2c63c0851048d8f7bff41ecf0f8cee05f52fd120..0000000000000000000000000000000000000000 --- a/contracts/simple.token/simple.token.abi +++ /dev/null @@ -1,2 +0,0 @@ -{ -} diff --git a/contracts/simple.token/simple.token.cpp b/contracts/simple.token/simple.token.cpp deleted file mode 100644 index 1f2ab97feca28e42881f22e0f5abcf8be089c108..0000000000000000000000000000000000000000 --- a/contracts/simple.token/simple.token.cpp +++ /dev/null @@ -1,49 +0,0 @@ -#include - -class simpletoken : public eosio::contract { - public: - simpletoken( account_name self ) - :contract(self),_accounts( _self, _self){} - - void transfer( account_name from, account_name to, uint64_t quantity ) { - require_auth( from ); - - const auto& fromacnt = _accounts.get( from ); - eosio_assert( fromacnt.balance >= quantity, "overdrawn balance" ); - _accounts.modify( fromacnt, from, [&]( auto& a ){ a.balance -= quantity; } ); - - add_balance( from, to, quantity ); - } - - void issue( account_name to, uint64_t quantity ) { - require_auth( _self ); - add_balance( _self, to, quantity ); - } - - private: - struct account { - account_name owner; - uint64_t balance; - - uint64_t primary_key()const { return owner; } - }; - - eosio::multi_index _accounts; - - void add_balance( account_name payer, account_name to, uint64_t q ) { - auto toitr = _accounts.find( to ); - if( toitr == _accounts.end() ) { - _accounts.emplace( payer, [&]( auto& a ) { - a.owner = to; - a.balance = q; - }); - } else { - _accounts.modify( toitr, 0, [&]( auto& a ) { - a.balance += q; - eosio_assert( a.balance >= q, "overflow detected" ); - }); - } - } -}; - -EOSIO_ABI( simpletoken, (transfer)(issue) ) diff --git a/contracts/social/CMakeLists.txt b/contracts/social/CMakeLists.txt deleted file mode 100644 index 72d5d9e059e10d0701cc03247835336d32b63db7..0000000000000000000000000000000000000000 --- a/contracts/social/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -add_wast_executable(TARGET social - INCLUDE_FOLDERS "${STANDARD_INCLUDE_FOLDERS}" - LIBRARIES eosiolib - DESTINATION_FOLDER ${CMAKE_CURRENT_BINARY_DIR} -) diff --git a/contracts/social/social.cpp b/contracts/social/social.cpp deleted file mode 100644 index 7cee3dd1ddff5b690778316445d352c9f344f162..0000000000000000000000000000000000000000 --- a/contracts/social/social.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/** - * @file - * @copyright defined in eos/LICENSE.txt - */ -#include - -/** - * The purpose of this contract is to implement something like Steem on EOS, this - * means this contract defines its own currency, allows people to create posts, vote - * on posts, and stake their voting power. - * - * Unlike Steem, the goal is to enable maximum parallelism and enable the currency to - * be easily integrated with an exchange contract. - */ - -struct post_action { - account_name author; - post_name postid; - account_name reply_to_author; - int32_t reply_to_id; - uint8_t author; /// index in notify list - char[] data; /// ignored, title is embedded within - - account_name get_author()const { return get_notify(author); } -}; - -struct vote_action { - account_name voter; - account_name author; - post_name postid; - int32_t vote_power; -}; - -struct post_record { - uint64_t total_votes = 0; - uint64_t claimed_votes = 0; - uint32_t created; - - post_record( uint32_t c = now() ):created(c){} - static Name table_id() { return Name("post"); } -}; - -struct account { - uint64_t social = 0; - uint64_t social_power = 0; - int32_t vote_power = 0; - uint32_t last_vote = 0; - - static Name table_id() { return Name("account"); } -}; - - -/** - * When a user posts we create a record that tracks the total votes and the time it - * was created. A user can submit this action multiple times, but subsequent calls do - * nothing. - * - * This method only does something when called in the context of the author, if - * any other contexts are notified - */ -void apply_social_post() { - const auto& post = current_action(); - require_auth( post.author ); - - eosio_assert( current_context() == post.author, "cannot call from any other context" ); - - static post_record& existing; - if( !Db::get( post.postid, existing ) ) - Db::store( post.postid, post_record( now() ) ); -} - -/** - * This action is called when a user casts a vote, it requires that this code is executed - * in the context of both the voter and the author. When executed in the author's context it - * updates the vote total. When executed - */ -void apply_social_vote() { - const auto& vote = current_action(); - require_recipient( vote.voter, vote.author ); - disable_context_code( vote.author() ); /// prevent the author's code from rejecting the potentially negative vote - - auto context = current_context(); - auto voter = vote.getVoter(); - - if( context == vote.author ) { - static post_record post; - eosio_assert( Db::get( vote.postid, post ) > 0, "unable to find post" ); - eosio_assert( now() - post.created < days(7), "cannot vote after 7 days" ); - post.votes += vote.vote_power; - Db::store( vote.postid, post ); - } - else if( context == vote.voter ) { - static account vote_account; - Db::get( "account", vote_account ); - auto abs_vote = abs(vote.vote_power); - vote_account.vote_power = min( vote_account.social_power, - vote_account.vote_power + (vote_account.social_power * (now()-last_vote)) / days(7)); - eosio_assert( abs_vote <= vote_account.vote_power, "insufficient vote power" ); - post.votes += vote.vote_power; - vote_account.vote_power -= abs_vote; - vote_account.last_vote = now(); - Db::store( "account", vote_account ); - } else { - eosio_assert( false, "invalid context for execution of this vote" ); - } -} - diff --git a/contracts/tic_tac_toe/tic_tac_toe.cpp b/contracts/tic_tac_toe/tic_tac_toe.cpp index cdbdc3d098d37fbdd592f79348b1b58069391057..ebc5cc46203c5d281cd63604d5860bf386ce7c4c 100644 --- a/contracts/tic_tac_toe/tic_tac_toe.cpp +++ b/contracts/tic_tac_toe/tic_tac_toe.cpp @@ -51,7 +51,7 @@ account_name get_winner(const tic_tac_toe::game& current_game) { uint32_t consecutive_diagonal_backslash = 3; uint32_t consecutive_diagonal_slash = 3; for (uint32_t i = 0; i < board.size(); i++) { - is_board_full &= is_empty_cell(board[i]); + is_board_full &= !is_empty_cell(board[i]); uint16_t row = uint16_t(i / tic_tac_toe::game::board_width); uint16_t column = uint16_t(i % tic_tac_toe::game::board_width); diff --git a/libraries/CMakeLists.txt b/libraries/CMakeLists.txt index 78593706c7d97c30892062f5468664c467c42c38..18013317c57816b80de3305d5d713bf03aa26865 100644 --- a/libraries/CMakeLists.txt +++ b/libraries/CMakeLists.txt @@ -3,11 +3,9 @@ add_subdirectory( builtins ) add_subdirectory( softfloat ) add_subdirectory( chainbase ) add_subdirectory( wasm-jit ) -add_subdirectory( utilities ) add_subdirectory( appbase ) add_subdirectory( chain ) add_subdirectory( testing ) -add_subdirectory( abi_generator ) #turn these off for now set(BUILD_TESTS OFF CACHE BOOL "Build GTest-based tests") diff --git a/libraries/abi_generator/CMakeLists.txt b/libraries/abi_generator/CMakeLists.txt deleted file mode 100644 index 88e32a84048252c87bb1fee4d83aaacaa05e240c..0000000000000000000000000000000000000000 --- a/libraries/abi_generator/CMakeLists.txt +++ /dev/null @@ -1,64 +0,0 @@ -# Find an installed build of LLVM -find_package(LLVM 4.0 REQUIRED CONFIG) -set( CMAKE_CXX_STANDARD 14 ) - -file(GLOB HEADERS "include/eosio/abi_generator/*.hpp") - -set(SOURCES ${HEADERS}) - -add_library( abi_generator - abi_generator.cpp - ${HEADERS} ) - -target_include_directories(abi_generator - PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" - "${LLVM_INCLUDE_DIRS}") - -target_link_libraries(abi_generator eosio_chain - clangRewrite - clangTooling - clangToolingCore - clangFrontend - clangDriver - clangSerialization - clangParse - clangSema - clangAnalysis - clangAST - clangBasic - clangEdit - clangLex -) - -target_link_libraries(abi_generator - LLVMX86AsmParser # MC, MCParser, Support, X86CodeGen, X86Desc, X86Info - LLVMX86CodeGen # Analysis, AsmPrinter, CodeGen, Core, MC, Support, Target, - # X86AsmPrinter, X86Desc, X86Info, X86Utils - LLVMX86Desc # MC, MCDisassembler, Object, Support, X86AsmPrinter, X86Info - LLVMX86AsmPrinter # MC, Support, X86Utils - LLVMX86Info # Support - LLVMX86Utils # Core, Support - LLVMCodeGen # Analysis, Core, MC, Scalar, Support, Target, TransformUtils - LLVMipo - LLVMScalarOpts - LLVMInstCombine - LLVMTransformUtils - LLVMTarget # Analysis, MC, Core, Support - LLVMAnalysis # Core, Support - LLVMOption # Support - LLVMMCDisassembler # MC, Support - LLVMMCParser # MC, Support - LLVMMC # Object, Support - LLVMProfileData # Core, Support, Object - LLVMObject # BitReader, Core, Support - LLVMBitReader # Core, Support - LLVMCore # BinaryFormat, Support - #LLVMBinaryFormat # Support - LLVMSupport # Demangle - LLVMDemangle -) - -if (USE_PCH) - set_target_properties(abi_generator PROPERTIES COTIRE_ADD_UNITY_BUILD FALSE) - cotire(eos_utilities) -endif(USE_PCH) diff --git a/libraries/abi_generator/abi_generator.cpp b/libraries/abi_generator/abi_generator.cpp deleted file mode 100644 index fc021c0a3fdf528b375e0131526df4be848bff10..0000000000000000000000000000000000000000 --- a/libraries/abi_generator/abi_generator.cpp +++ /dev/null @@ -1,688 +0,0 @@ -#include -#include - -namespace eosio { - -void abi_generator::set_target_contract(const string& contract, const vector& actions) { - target_contract = contract; - target_actions = actions; -} - -void abi_generator::enable_optimizaton(abi_generator::optimization o) { - optimizations |= o; -} - -bool abi_generator::is_opt_enabled(abi_generator::optimization o) { - return (optimizations & o) != 0; -} - -void abi_generator::set_output(abi_def& output) { - this->output = &output; -} - -void abi_generator::set_verbose(bool verbose) { - this->verbose = verbose; -} - -void abi_generator::set_ricardian_contracts(const ricardian_contracts& contracts) { - this->rc = contracts; -} - -void abi_generator::set_abi_context(const string& abi_context) { - this->abi_context = abi_context; -} - -void abi_generator::set_compiler_instance(CompilerInstance& compiler_instance) { - this->compiler_instance = &compiler_instance; -} - -void abi_generator::handle_tagdecl_definition(TagDecl* tag_decl) { - ast_context = &tag_decl->getASTContext(); - auto decl_location = tag_decl->getLocation().printToString(ast_context->getSourceManager()); - try { - handle_decl(tag_decl); -} FC_CAPTURE_AND_RETHROW((decl_location)) } - -string abi_generator::remove_namespace(const string& full_name) { - int i = full_name.size(); - int on_spec = 0; - int colons = 0; - while( --i >= 0 ) { - if( full_name[i] == '>' ) { - ++on_spec; colons=0; - } else if( full_name[i] == '<' ) { - --on_spec; colons=0; - } else if( full_name[i] == ':' && !on_spec) { - if (++colons == 2) - return full_name.substr(i+2); - } else { - colons = 0; - } - } - return full_name; -} - -bool abi_generator::is_builtin_type(const string& type_name) { - abi_serializer serializer; - auto rtype = resolve_type(type_name); - return serializer.is_builtin_type(translate_type(rtype)); -} - -string abi_generator::translate_type(const string& type_name) { - string built_in_type = type_name; - - if (type_name == "unsigned __int128" || type_name == "uint128_t") built_in_type = "uint128"; - else if (type_name == "__int128" || type_name == "int128_t") built_in_type = "int128"; - - else if (type_name == "unsigned long long" || type_name == "uint64_t") built_in_type = "uint64"; - else if (type_name == "unsigned long" || type_name == "uint32_t") built_in_type = "uint32"; - else if (type_name == "unsigned short" || type_name == "uint16_t") built_in_type = "uint16"; - else if (type_name == "unsigned char" || type_name == "uint8_t") built_in_type = "uint8"; - - else if (type_name == "long long" || type_name == "int64_t") built_in_type = "int64"; - else if (type_name == "long" || type_name == "int32_t") built_in_type = "int32"; - else if (type_name == "short" || type_name == "int16_t") built_in_type = "int16"; - else if (type_name == "char" || type_name == "int8_t") built_in_type = "int8"; - else if (type_name == "double") built_in_type = "float64"; - else { - static auto types = eosio::chain::common_type_defs(); - auto itr = std::find_if( types.begin(), types.end(), - [&type_name]( const eosio::chain::type_def& t ) { return t.new_type_name == type_name; } ); - if( itr != types.end()) { - built_in_type = itr->type; - } - } - - return built_in_type; -} - -bool abi_generator::inspect_type_methods_for_actions(const Decl* decl) { try { - - const auto* rec_decl = dyn_cast(decl); - if(rec_decl == nullptr) return false; - - const auto* type = rec_decl->getTypeForDecl(); - ABI_ASSERT(type != nullptr); - - bool at_least_one_action = false; - - auto export_method = [&](const CXXMethodDecl* method) { - - auto method_name = method->getNameAsString(); - - // Try to get "action" annotation from method comment - bool raw_comment_is_action = false; - string action_name_from_comment; - const RawComment* raw_comment = ast_context->getRawCommentForDeclNoCache(method); - if(raw_comment != nullptr) { - SourceManager& source_manager = ast_context->getSourceManager(); - string raw_text = raw_comment->getRawText(source_manager); - regex r(R"(@abi (action) ?((?:[a-z0-9]+)*))"); - smatch smatch; - regex_search(raw_text, smatch, r); - raw_comment_is_action = smatch.size() == 3; - - if (raw_comment_is_action) { - action_name_from_comment = smatch[2]; - } - } - - // Check if current method is listed the EOSIO_ABI macro - bool is_action_from_macro = rec_decl->getName().str() == target_contract && std::find(target_actions.begin(), target_actions.end(), method_name) != target_actions.end(); - - if(!raw_comment_is_action && !is_action_from_macro) { - return; - } - - ABI_ASSERT(find_struct(method_name) == nullptr, "action already exists ${method_name}", ("method_name",method_name)); - - struct_def abi_struct; - for(const auto* p : method->parameters() ) { - clang::QualType qt = p->getOriginalType().getNonReferenceType(); - qt.setLocalFastQualifiers(0); - - string field_name = p->getNameAsString(); - string field_type_name = add_type(qt, 0); - - field_def struct_field{field_name, field_type_name}; - ABI_ASSERT(is_builtin_type(get_vector_element_type(struct_field.type)) - || find_struct(get_vector_element_type(struct_field.type)) - || find_type(get_vector_element_type(struct_field.type)) - , "Unknown type ${type} [${abi}]",("type",struct_field.type)("abi",*output)); - - type_size[string(struct_field.type)] = is_vector(struct_field.type) ? 0 : ast_context->getTypeSize(qt); - abi_struct.fields.push_back(struct_field); - } - - abi_struct.name = method_name; - abi_struct.base = ""; - - output->structs.push_back(abi_struct); - - full_types[method_name] = method_name; - - string action_name = action_name_from_comment.empty() ? method_name : action_name_from_comment; - output->actions.push_back({action_name, method_name, rc[method_name]}); - at_least_one_action = true; - }; - - const auto export_methods = [&export_method](const CXXRecordDecl* rec_decl) { - - - auto export_methods_impl = [&export_method](const CXXRecordDecl* rec_decl, auto& ref) -> void { - - - auto tmp = rec_decl->bases(); - auto rec_name = rec_decl->getName().str(); - - rec_decl->forallBases([&ref](const CXXRecordDecl* base) -> bool { - ref(base, ref); - return true; - }); - - for(const auto* method : rec_decl->methods()) { - export_method(method); - } - - }; - - export_methods_impl(rec_decl, export_methods_impl); - }; - - export_methods(rec_decl); - - return at_least_one_action; - -} FC_CAPTURE_AND_RETHROW() } - -void abi_generator::handle_decl(const Decl* decl) { try { - - ABI_ASSERT(decl != nullptr); - ABI_ASSERT(output != nullptr); - ABI_ASSERT(ast_context != nullptr); - - // Only process declarations that has the `abi_context` folder as parent. - SourceManager& source_manager = ast_context->getSourceManager(); - auto file_name = source_manager.getFilename(decl->getLocStart()); - if ( !abi_context.empty() && !file_name.startswith(abi_context) ) { - return; - } - - // Check if the current declaration has actions (EOSIO_ABI, or explicit) - bool type_has_actions = inspect_type_methods_for_actions(decl); - if( type_has_actions ) return; - - // The current Decl doesn't have actions - const RawComment* raw_comment = ast_context->getRawCommentForDeclNoCache(decl); - if(raw_comment == nullptr) { - return; - } - - string raw_text = raw_comment->getRawText(source_manager); - regex r; - - // If EOSIO_ABI macro was found, we will only check if the current Decl - // is intented to be an ABI table record, otherwise we check for both (action or table) - if( target_contract.size() ) - r = regex(R"(@abi (table)((?: [a-z0-9]+)*))"); - else - r = regex(R"(@abi (action|table)((?: [a-z0-9]+)*))"); - - smatch smatch; - while(regex_search(raw_text, smatch, r)) - { - if(smatch.size() == 3) { - - auto type = smatch[1].str(); - - vector params; - auto string_params = smatch[2].str(); - boost::trim(string_params); - if(!string_params.empty()) - boost::split(params, string_params, boost::is_any_of(" ")); - - if(type == "action") { - - const auto* action_decl = dyn_cast(decl); - ABI_ASSERT(action_decl != nullptr); - - auto qt = action_decl->getTypeForDecl()->getCanonicalTypeInternal(); - - auto type_name = add_struct(qt, "", 0); - ABI_ASSERT(!is_builtin_type(type_name), - "A built-in type with the same name exists, try using another name: ${type_name}", ("type_name",type_name)); - - if(params.size()==0) { - params.push_back( boost::algorithm::to_lower_copy(boost::erase_all_copy(type_name, "_")) ); - } - - for(const auto& action : params) { - const auto* ac = find_action(action); - if( ac ) { - ABI_ASSERT(ac->type == type_name, "Same action name with different type ${action}",("action",action)); - continue; - } - output->actions.push_back({action, type_name, rc[action]}); - } - - } else if (type == "table") { - - const auto* table_decl = dyn_cast(decl); - ABI_ASSERT(table_decl != nullptr); - - auto qt = table_decl->getTypeForDecl()->getCanonicalTypeInternal(); - auto type_name = add_struct(qt, "", 0); - - ABI_ASSERT(!is_builtin_type(type_name), - "A built-in type with the same name exists, try using another name: ${type_name}", ("type_name",type_name)); - - const auto* s = find_struct(type_name); - ABI_ASSERT(s, "Unable to find type ${type}", ("type",type_name)); - - table_def table; - table.name = boost::algorithm::to_lower_copy(boost::erase_all_copy(type_name, "_")); - table.type = type_name; - - if(params.size() >= 1) { - table.name = params[0]; - } - - if(params.size() >= 2) { - table.index_type = params[1]; - ABI_ASSERT(table.index_type == "i64", "Only i64 index is supported. ${index_type}",("index_type",table.index_type)); - } else { try { - guess_index_type(table, *s); - } FC_CAPTURE_AND_RETHROW( (type_name) ) } - - try { - guess_key_names(table, *s); - } FC_CAPTURE_AND_RETHROW( (type_name) ) - - //TODO: assert that we are adding the same table - const auto* ta = find_table(table.name); - if(!ta) { - output->tables.push_back(table); - } - } - } - - raw_text = smatch.suffix(); - } - -} FC_CAPTURE_AND_RETHROW() } - -bool abi_generator::is_64bit(const string& type) { - return type_size[type] == 64; -} - -bool abi_generator::is_128bit(const string& type) { - return type_size[type] == 128; -} - -bool abi_generator::is_string(const string& type) { - return type == "String" || type == "string"; -} - -void abi_generator::get_all_fields(const struct_def& s, vector& fields) { - abi_serializer abis(*output, fc::seconds(1)); // No risk to client side serialization taking a long time - - for(const auto& field : s.fields) { - fields.push_back(field); - } - - if(s.base.size()) { - const auto* base = find_struct(s.base); - ABI_ASSERT(base, "Unable to find base type ${type}",("type",s.base)); - get_all_fields(*base, fields); - } -} - -bool abi_generator::is_i64_index(const vector& fields) { - return fields.size() >= 1 && is_64bit(fields[0].type); -} - -void abi_generator::guess_index_type(table_def& table, const struct_def s) { - vector fields; - get_all_fields(s, fields); - if( is_i64_index(fields) ) { - table.index_type = "i64"; - } else { - ABI_ASSERT(false, "Unable to guess index type"); - } -} - -void abi_generator::guess_key_names(table_def& table, const struct_def s) { - - vector fields; - get_all_fields(s, fields); - - if( table.index_type == "i64") { - - table.key_names.clear(); - table.key_types.clear(); - - unsigned int key_size = 0; - bool valid_key = false; - for(auto& f : fields) { - table.key_names.emplace_back(f.name); - table.key_types.emplace_back(f.type); - key_size += type_size[f.type]/8; - - if(table.index_type == "i64" && key_size >= sizeof(uint64_t)) { - valid_key = true; - break; - } - } - - ABI_ASSERT(valid_key, "Unable to guess key names"); - } else { - ABI_ASSERT(false, "Unable to guess key names"); - } -} - -const table_def* abi_generator::find_table(const table_name& name) { - for( const auto& ta : output->tables ) { - if(ta.name == name) { - return &ta; - } - } - return nullptr; -} - -const type_def* abi_generator::find_type(const type_name& new_type_name) { - for( const auto& td : output->types ) { - if(td.new_type_name == new_type_name) { - return &td; - } - } - return nullptr; -} - -const action_def* abi_generator::find_action(const action_name& name) { - for( const auto& ac : output->actions ) { - if(ac.name == name) { - return ∾ - } - } - return nullptr; -} - -const struct_def* abi_generator::find_struct(const type_name& name) { - auto rname = resolve_type(name); - for( const auto& st : output->structs ) { - if(st.name == rname) { - return &st; - } - } - return nullptr; -} - -type_name abi_generator::resolve_type(const type_name& type){ - const auto* td = find_type(type); - if( td ) { - for( auto i = output->types.size(); i > 0; --i ) { // avoid infinite recursion - const type_name& t = td->type; - td = find_type(t); - if( td == nullptr ) return t; - } - } - return type; -} - -bool abi_generator::is_one_filed_no_base(const string& type_name) { - const auto* s = find_struct(type_name); - return s && s->base.size() == 0 && s->fields.size() == 1; -} - -string abi_generator::decl_to_string(clang::Decl* d) { - //ASTContext& ctx = d->getASTContext(); - const auto& sm = ast_context->getSourceManager(); - clang::SourceLocation b(d->getLocStart()), _e(d->getLocEnd()); - clang::SourceLocation e(clang::Lexer::getLocForEndOfToken(_e, 0, sm, compiler_instance->getLangOpts())); - return string(sm.getCharacterData(b), - sm.getCharacterData(e)-sm.getCharacterData(b)); -} - -bool abi_generator::is_typedef(const clang::QualType& qt) { - return isa(qt.getTypePtr()); -} - -bool abi_generator::is_elaborated(const clang::QualType& qt) { - return isa(qt.getTypePtr()); -} - -bool abi_generator::is_vector(const clang::QualType& vqt) { - - QualType qt(vqt); - - if ( is_elaborated(qt) ) - qt = qt->getAs()->getNamedType(); - - return isa(qt.getTypePtr()) \ - && boost::starts_with( get_type_name(qt, false), "vector"); -} - -bool abi_generator::is_vector(const string& type_name) { - return boost::ends_with(type_name, "[]"); -} - -bool abi_generator::is_struct_specialization(const clang::QualType& qt) { - return is_struct(qt) && isa(qt.getTypePtr()); -} - -bool abi_generator::is_struct(const clang::QualType& sqt) { - clang::QualType qt(sqt); - const auto* type = qt.getTypePtr(); - return !is_vector(qt) && (type->isStructureType() || type->isClassType()); -} - -clang::QualType abi_generator::get_vector_element_type(const clang::QualType& qt) { - const auto* tst = clang::dyn_cast(qt.getTypePtr()); - ABI_ASSERT(tst != nullptr); - const clang::TemplateArgument& arg0 = tst->getArg(0); - return arg0.getAsType(); -} - -string abi_generator::get_vector_element_type(const string& type_name) { - if( is_vector(type_name) ) - return type_name.substr(0, type_name.size()-2); - return type_name; -} - -string abi_generator::get_type_name(const clang::QualType& qt, bool with_namespace=false) { - auto name = clang::TypeName::getFullyQualifiedName(qt, *ast_context); - if(!with_namespace) - name = remove_namespace(name); - return name; -} - -clang::QualType abi_generator::add_typedef(const clang::QualType& tqt, size_t recursion_depth) { - - ABI_ASSERT( ++recursion_depth < max_recursion_depth, "recursive definition, max_recursion_depth" ); - - clang::QualType qt(get_named_type_if_elaborated(tqt)); - - const auto* td_decl = qt->getAs()->getDecl(); - auto underlying_type = td_decl->getUnderlyingType().getUnqualifiedType(); - - auto new_type_name = td_decl->getName().str(); - auto underlying_type_name = get_type_name(underlying_type); - - if ( is_vector(underlying_type) ) { - underlying_type_name = add_vector(underlying_type, recursion_depth); - } - - type_def abi_typedef; - abi_typedef.new_type_name = new_type_name; - abi_typedef.type = translate_type(underlying_type_name); - const auto* td = find_type(abi_typedef.new_type_name); - - if(!td && !is_struct_specialization(underlying_type) ) { - output->types.push_back(abi_typedef); - } else { - if(td) ABI_ASSERT(abi_typedef.type == td->type); - } - - if( is_typedef(underlying_type) && !is_builtin_type(get_type_name(underlying_type)) ) - return add_typedef(underlying_type, recursion_depth); - - return underlying_type; -} - -clang::CXXRecordDecl::base_class_range abi_generator::get_struct_bases(const clang::QualType& sqt) { - - clang::QualType qt(sqt); - if(is_typedef(qt)) { - const auto* td_decl = qt->getAs()->getDecl(); - qt = td_decl->getUnderlyingType().getUnqualifiedType(); - } - - const auto* record_type = qt->getAs(); - ABI_ASSERT(record_type != nullptr); - auto cxxrecord_decl = clang::dyn_cast(record_type->getDecl()); - ABI_ASSERT(cxxrecord_decl != nullptr); - //record_type->getCanonicalTypeInternal().dump(); - ABI_ASSERT(cxxrecord_decl->hasDefinition(), "No definition for ${t}", ("t", qt.getAsString())); - - auto bases = cxxrecord_decl->bases(); - - return bases; -} - -const clang::RecordDecl::field_range abi_generator::get_struct_fields(const clang::QualType& sqt) { - clang::QualType qt(sqt); - - if(is_typedef(qt)) { - const auto* td_decl = qt->getAs()->getDecl(); - qt = td_decl->getUnderlyingType().getUnqualifiedType(); - } - - const auto* record_type = qt->getAs(); - ABI_ASSERT(record_type != nullptr); - return record_type->getDecl()->fields(); -} - -string abi_generator::add_vector(const clang::QualType& vqt, size_t recursion_depth) { - - ABI_ASSERT( ++recursion_depth < max_recursion_depth, "recursive definition, max_recursion_depth" ); - - clang::QualType qt(get_named_type_if_elaborated(vqt)); - - auto vector_element_type = get_vector_element_type(qt); - ABI_ASSERT(!is_vector(vector_element_type), "Only one-dimensional arrays are supported"); - - add_type(vector_element_type, recursion_depth); - - auto vector_element_type_str = translate_type(get_type_name(vector_element_type)); - vector_element_type_str += "[]"; - - return vector_element_type_str; -} - -string abi_generator::add_type(const clang::QualType& tqt, size_t recursion_depth) { - - ABI_ASSERT( ++recursion_depth < max_recursion_depth, "recursive definition, max_recursion_depth" ); - - clang::QualType qt(get_named_type_if_elaborated(tqt)); - - string full_type_name = translate_type(get_type_name(qt, true)); - string type_name = translate_type(get_type_name(qt)); - bool is_type_def = false; - - if( is_builtin_type(type_name) ) { - return type_name; - } - - if( is_typedef(qt) ) { - qt = add_typedef(qt, recursion_depth); - if( is_builtin_type(translate_type(get_type_name(qt))) ) { - return type_name; - } - is_type_def = true; - } - - if( is_vector(qt) ) { - auto vector_type_name = add_vector(qt, recursion_depth); - return is_type_def ? type_name : vector_type_name; - } - - if( is_struct(qt) ) { - return add_struct(qt, full_type_name, recursion_depth); - } - - ABI_ASSERT(false, "types can only be: vector, struct, class or a built-in type. (${type}) ", ("type",get_type_name(qt))); - return type_name; -} - -clang::QualType abi_generator::get_named_type_if_elaborated(const clang::QualType& qt) { - if( is_elaborated(qt) ) { - return qt->getAs()->getNamedType(); - } - return qt; -} - -string abi_generator::add_struct(const clang::QualType& sqt, string full_name, size_t recursion_depth) { - - ABI_ASSERT( ++recursion_depth < max_recursion_depth, "recursive definition, max_recursion_depth" ); - - clang::QualType qt(get_named_type_if_elaborated(sqt)); - - if( full_name.empty() ) { - full_name = get_type_name(qt, true); - } - - auto name = remove_namespace(full_name); - - ABI_ASSERT(is_struct(qt), "Only struct and class are supported. ${full_name}",("full_name",full_name)); - - if( find_struct(name) ) { - auto itr = full_types.find(resolve_type(name)); - if(itr != full_types.end()) { - ABI_ASSERT(itr->second == full_name, "Unable to add type '${full_name}' because '${conflict}' is already in.\n${t}", ("full_name",full_name)("conflict",itr->second)("t",output->types)); - } - return name; - } - - auto bases = get_struct_bases(qt); - auto bitr = bases.begin(); - int total_bases = 0; - - string base_name; - while( bitr != bases.end() ) { - auto base_qt = bitr->getType(); - const auto* record_type = base_qt->getAs(); - if( record_type && is_struct(base_qt) && !record_type->getDecl()->field_empty() ) { - ABI_ASSERT(total_bases == 0, "Multiple inheritance not supported - ${type}", ("type",full_name)); - base_name = add_type(base_qt, recursion_depth); - ++total_bases; - } - ++bitr; - } - - struct_def abi_struct; - for (const clang::FieldDecl* field : get_struct_fields(qt) ) { - clang::QualType qt = field->getType(); - - string field_name = field->getNameAsString(); - string field_type_name = add_type(qt, recursion_depth); - - field_def struct_field{field_name, field_type_name}; - ABI_ASSERT(is_builtin_type(get_vector_element_type(struct_field.type)) - || find_struct(get_vector_element_type(struct_field.type)) - || find_type(get_vector_element_type(struct_field.type)) - , "Unknown type ${type} [${abi}]",("type",struct_field.type)("abi",*output)); - - type_size[string(struct_field.type)] = is_vector(struct_field.type) ? 0 : ast_context->getTypeSize(qt); - abi_struct.fields.push_back(struct_field); - } - - abi_struct.name = resolve_type(name); - abi_struct.base = base_name; - - output->structs.push_back(abi_struct); - - full_types[name] = full_name; - return name; -} - -} diff --git a/libraries/abi_generator/include/eosio/abi_generator/abi_generator.hpp b/libraries/abi_generator/include/eosio/abi_generator/abi_generator.hpp deleted file mode 100644 index 9248846cd88910be5a3125364b08ac2b921943a4..0000000000000000000000000000000000000000 --- a/libraries/abi_generator/include/eosio/abi_generator/abi_generator.hpp +++ /dev/null @@ -1,442 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -//clashes with something deep in the AST includes in clang 6 and possibly other versions of clang -#pragma push_macro("N") -#undef N - -#include "clang/Driver/Options.h" -#include "clang/AST/AST.h" -#include "clang/AST/ASTContext.h" -#include "clang/AST/ASTConsumer.h" - -#include "clang/Frontend/FrontendPluginRegistry.h" -#include "clang/AST/AST.h" -#include "clang/AST/ASTConsumer.h" -#include "clang/AST/RecursiveASTVisitor.h" -#include "clang/Frontend/CompilerInstance.h" -#include "clang/Frontend/FrontendActions.h" -#include "clang/Sema/Sema.h" -#include "clang/Lex/Preprocessor.h" -#include "clang/Lex/MacroArgs.h" -#include "clang/Tooling/Tooling.h" -#include "clang/Tooling/CommonOptionsParser.h" -#include "clang/Tooling/Core/QualTypeNames.h" -#include "llvm/Support/raw_ostream.h" -#include -#include - -using namespace clang; -using namespace std; -using namespace clang::tooling; -namespace cl = llvm::cl; - -namespace eosio { - using namespace eosio::chain; - - FC_DECLARE_EXCEPTION( abi_generation_exception, 999999, "Unable to generate abi" ); - - #define ABI_ASSERT( TEST, ... ) \ - FC_EXPAND_MACRO( \ - FC_MULTILINE_MACRO_BEGIN \ - if( UNLIKELY(!(TEST)) ) \ - { \ - if( fc::enable_record_assert_trip ) \ - fc::record_assert_trip( __FILE__, __LINE__, #TEST ); \ - FC_THROW_EXCEPTION( eosio::abi_generation_exception, #TEST ": " __VA_ARGS__ ); \ - } \ - FC_MULTILINE_MACRO_END \ - ) - - class ricardian_contracts { - public: - ricardian_contracts() = default; - ricardian_contracts( const string& context, const string& contract, const vector& actions ) { - ifstream clauses_file( context+"/"+contract+"_rc.md"); - if ( !clauses_file.good() ) - wlog("Warning, no ricardian clauses found for ${con}\n", ("con", contract)); - else - parse_clauses( clauses_file ); - - for ( auto act : actions ) { - ifstream contract_file( context+"/"+contract+"."+act+"_rc.md" ); - if ( !contract_file.good() ) - wlog("Warning, no ricardian contract found for ${act}\n", ("act", act)); - else { - parse_contract( contract_file ); - } - } - } - - vector get_clauses() { - return _clauses; - } - string operator[]( string key ) { - return _contracts[key]; - } - private: - inline string is_clause_decl( string line ) { - smatch match; - if ( regex_match( line, match, regex("(###[ ]+CLAUSE[ ]+NAME[ ]*:[ ]*)(.*)", regex_constants::ECMAScript) ) ) { - EOS_ASSERT( match.size() == 3, invalid_ricardian_clause_exception, "Error, malformed clause declaration" ); - return match[2].str(); - } - return {}; - } - - inline string is_action_decl( string line ) { - smatch match; - if ( regex_match( line, match, regex("(##[ ]+ACTION[ ]+NAME[ ]*:[ ]*)(.*)", regex_constants::ECMAScript) ) ) { - EOS_ASSERT( match.size() == 3, invalid_ricardian_action_exception, "Error, malformed action declaration" ); - return match[2].str(); - } - return {}; - } - - void parse_contract( ifstream& contract_file ) { - string line; - string name; - string _name; - stringstream body; - bool first_time = true; - while ( contract_file.peek() != EOF ) { - getline( contract_file, line ); - body << line; - if ( !(_name = is_action_decl( line )).empty() ) { - name = _name; - first_time = false; - } - else - if ( !first_time ) - body << line << '\n'; - } - - _contracts.emplace(name, body.str()); - } - - void parse_clauses( ifstream& clause_file ) { - string line; - string name; - string _name; - stringstream body; - bool first_time = true; - while ( clause_file.peek() != EOF ) { - getline( clause_file, line ); - - if ( !(_name = is_clause_decl( line )).empty() ) { - if ( !first_time ) { - if (body.str().empty() ) { - EOS_ASSERT( false, invalid_ricardian_clause_exception, "Error, invalid input in ricardian clauses, no body found" ); - } - _clauses.emplace_back( name, body.str() ); - body.str(""); - } - name = _name; - first_time = false; - } - else - if ( !first_time ) - body << line << '\n'; - } - - } - vector _clauses; - map _contracts; - }; - - /** - * @brief Generates eosio::abi_def struct handling events from ASTConsumer - */ - class abi_generator { - private: - static constexpr size_t max_recursion_depth = 25; // arbitrary depth to prevent infinite recursion - bool verbose; - int optimizations; - abi_def* output; - CompilerInstance* compiler_instance; - map type_size; - map full_types; - string abi_context; - clang::ASTContext* ast_context; - string target_contract; - vector target_actions; - ricardian_contracts rc; - - public: - - enum optimization { - OPT_SINGLE_FIELD_STRUCT - }; - - abi_generator() - : verbose(false) - , optimizations(0) - , output(nullptr) - , compiler_instance(nullptr) - , ast_context(nullptr) - {} - - ~abi_generator() {} - - /** - * @brief Enable optimization when generating ABI - * @param o optimization to enable - */ - void enable_optimizaton(optimization o); - - /** - * @brief Check if an optimization is enabled - * @param o optimization to check - */ - bool is_opt_enabled(optimization o); - - /** - * @brief Set the destination ABI struct to write - * @param output ABI destination - */ - void set_output(abi_def& output); - - /** - * @brief Enable/Disable verbose status messages - * @param verbose enable/disable flag - */ - void set_verbose(bool verbose); - - /** - * @brief Set the root folder that limits where types will be imported. Types declared in header files located in child sub-folders will also be exported - * @param abi_context folder - */ - void set_abi_context(const string& abi_context); - - /** - * @brief Set the ricardian_contracts object with parsed contracts and clauses - * @param ricardian_contracts contracts - */ - void set_ricardian_contracts(const ricardian_contracts& contracts); - - - /** - * @brief Set the single instance of the Clang compiler - * @param compiler_instance compiler instance - */ - void set_compiler_instance(CompilerInstance& compiler_instance); - - /** - * @brief Handle declaration of struct/union/enum - * @param tag_decl declaration to handle - */ - void handle_tagdecl_definition(TagDecl* tag_decl); - - void set_target_contract(const string& contract, const vector& actions); - - private: - bool inspect_type_methods_for_actions(const Decl* decl); - - string remove_namespace(const string& full_name); - - bool is_builtin_type(const string& type_name); - - string translate_type(const string& type_name); - - void handle_decl(const Decl* decl); - - bool is_64bit(const string& type); - - bool is_128bit(const string& type); - - bool is_string(const string& type); - - void get_all_fields(const struct_def& s, vector& fields); - - bool is_i64i64i64_index(const vector& fields); - - bool is_i64_index(const vector& fields); - - bool is_i128i128_index(const vector& fields); - - bool is_str_index(const vector& fields); - - void guess_index_type(table_def& table, const struct_def s); - - void guess_key_names(table_def& table, const struct_def s); - - const table_def* find_table(const table_name& name); - - const type_def* find_type(const type_name& new_type_name); - - const action_def* find_action(const action_name& name); - - const struct_def* find_struct(const type_name& name); - - type_name resolve_type(const type_name& type); - - bool is_one_filed_no_base(const string& type_name); - - string decl_to_string(clang::Decl* d); - - bool is_typedef(const clang::QualType& qt); - QualType add_typedef(const clang::QualType& qt, size_t recursion_depth); - - bool is_vector(const clang::QualType& qt); - bool is_vector(const string& type_name); - string add_vector(const clang::QualType& qt, size_t recursion_depth); - - bool is_struct(const clang::QualType& qt); - string add_struct(const clang::QualType& qt, string full_type_name, size_t recursion_depth); - - string get_type_name(const clang::QualType& qt, bool no_namespace); - string add_type(const clang::QualType& tqt, size_t recursion_depth); - - bool is_elaborated(const clang::QualType& qt); - bool is_struct_specialization(const clang::QualType& qt); - - QualType get_vector_element_type(const clang::QualType& qt); - string get_vector_element_type(const string& type_name); - - clang::QualType get_named_type_if_elaborated(const clang::QualType& qt); - - const clang::RecordDecl::field_range get_struct_fields(const clang::QualType& qt); - clang::CXXRecordDecl::base_class_range get_struct_bases(const clang::QualType& qt); - }; - - struct abi_generator_astconsumer : public ASTConsumer { - abi_generator& abi_gen; - - abi_generator_astconsumer(CompilerInstance& compiler_instance, abi_generator& abi_gen) - :abi_gen(abi_gen) - { - abi_gen.set_compiler_instance(compiler_instance); - } - - void HandleTagDeclDefinition(TagDecl* tag_decl) override { - abi_gen.handle_tagdecl_definition(tag_decl); - } - }; - - struct find_eosio_abi_macro_action : public PreprocessOnlyAction { - - string& contract; - vector& actions; - const string& abi_context; - - find_eosio_abi_macro_action(string& contract, vector& actions, const string& abi_context - ): contract(contract), - actions(actions), abi_context(abi_context) { - } - - struct callback_handler : public PPCallbacks { - - CompilerInstance& compiler_instance; - find_eosio_abi_macro_action& act; - - callback_handler(CompilerInstance& compiler_instance, find_eosio_abi_macro_action& act) - : compiler_instance(compiler_instance), act(act) {} - - string remove_namespace(const string& full_name) { - int i = full_name.size(); - int on_spec = 0; - int colons = 0; - while( --i >= 0 ) { - if( full_name[i] == '>' ) { - ++on_spec; colons=0; - } else if( full_name[i] == '<' ) { - --on_spec; colons=0; - } else if( full_name[i] == ':' && !on_spec) { - if (++colons == 2) - return full_name.substr(i+2); - } else { - colons = 0; - } - } - return full_name; - } - - void MacroExpands (const Token &token, const MacroDefinition &md, SourceRange range, const MacroArgs *args) override { - - auto* id = token.getIdentifierInfo(); - if( id == nullptr ) return; - if( id->getName() != "EOSIO_ABI" ) return; - - const auto& sm = compiler_instance.getSourceManager(); - auto file_name = sm.getFilename(range.getBegin()); - if ( !act.abi_context.empty() && !file_name.startswith(act.abi_context) ) { - return; - } - - ABI_ASSERT( md.getMacroInfo()->getNumArgs() == 2 ); - - clang::SourceLocation b(range.getBegin()), _e(range.getEnd()); - clang::SourceLocation e(clang::Lexer::getLocForEndOfToken(_e, 0, sm, compiler_instance.getLangOpts())); - auto macrostr = string(sm.getCharacterData(b), sm.getCharacterData(e)-sm.getCharacterData(b)); - - regex r(R"(EOSIO_ABI\s*\(\s*(.+?)\s*,((?:.+?)*)\s*\))"); - smatch smatch; - auto res = regex_search(macrostr, smatch, r); - ABI_ASSERT( res ); - - act.contract = remove_namespace(smatch[1].str()); - - auto actions_str = smatch[2].str(); - boost::trim(actions_str); - actions_str = actions_str.substr(1); - actions_str.pop_back(); - boost::remove_erase_if(actions_str, boost::is_any_of(" (")); - - boost::split(act.actions, actions_str, boost::is_any_of(")")); - } - }; - - void ExecuteAction() override { - getCompilerInstance().getPreprocessor().addPPCallbacks( - llvm::make_unique(getCompilerInstance(), *this) - ); - PreprocessOnlyAction::ExecuteAction(); - }; - - }; - - - class generate_abi_action : public ASTFrontendAction { - - private: - set parsed_templates; - abi_generator abi_gen; - - public: - - generate_abi_action(bool verbose, bool opt_sfs, string abi_context, - abi_def& output, const string& contract, const vector& actions) { - - ricardian_contracts rc( abi_context, contract, actions ); - abi_gen.set_output(output); - abi_gen.set_verbose(verbose); - abi_gen.set_abi_context(abi_context); - abi_gen.set_target_contract(contract, actions); - abi_gen.set_ricardian_contracts( rc ); - output.ricardian_clauses = rc.get_clauses(); - - if(opt_sfs) - abi_gen.enable_optimizaton(abi_generator::OPT_SINGLE_FIELD_STRUCT); - } - - protected: - std::unique_ptr CreateASTConsumer(CompilerInstance& compiler_instance, - llvm::StringRef) override { - return llvm::make_unique(compiler_instance, abi_gen); - } - }; - -} //ns eosio - -#pragma pop_macro("N") diff --git a/libraries/appbase b/libraries/appbase index f3a63c1c04df957c0675b51d298851c71d6ccbe7..1d6e6e4a0b334553658fe05cfa1e86081b6d0b4a 160000 --- a/libraries/appbase +++ b/libraries/appbase @@ -1 +1 @@ -Subproject commit f3a63c1c04df957c0675b51d298851c71d6ccbe7 +Subproject commit 1d6e6e4a0b334553658fe05cfa1e86081b6d0b4a diff --git a/libraries/chain/CMakeLists.txt b/libraries/chain/CMakeLists.txt index a8eeadaa94a595381307e8cc27018dec1563ee6c..ee8fe1ebab2603ec2b9e1b87865677238a45f68f 100644 --- a/libraries/chain/CMakeLists.txt +++ b/libraries/chain/CMakeLists.txt @@ -50,7 +50,7 @@ add_library( eosio_chain ${HEADERS} ) -target_link_libraries( eosio_chain eos_utilities fc chainbase Logging IR WAST WASM Runtime +target_link_libraries( eosio_chain fc chainbase Logging IR WAST WASM Runtime softfloat builtins wabt ) target_include_directories( eosio_chain diff --git a/libraries/chain/apply_context.cpp b/libraries/chain/apply_context.cpp index de1450013d88a51e4599516f508fe913ef979ab5..c7b0fc37125d1286503cd75fb9016bfddae5654e 100644 --- a/libraries/chain/apply_context.cpp +++ b/libraries/chain/apply_context.cpp @@ -51,7 +51,7 @@ void apply_context::exec_one( action_trace& trace ) privileged = a.privileged; auto native = control.find_apply_handler( receiver, act.account, act.name ); if( native ) { - if( trx_context.can_subjectively_fail && control.is_producing_block() ) { + if( trx_context.enforce_whiteblacklist && control.is_producing_block() ) { control.check_contract_list( receiver ); control.check_action_list( act.account, act.name ); } @@ -61,7 +61,7 @@ void apply_context::exec_one( action_trace& trace ) if( a.code.size() > 0 && !(act.account == config::system_account_name && act.name == N( setcode ) && receiver == config::system_account_name) ) { - if( trx_context.can_subjectively_fail && control.is_producing_block() ) { + if( trx_context.enforce_whiteblacklist && control.is_producing_block() ) { control.check_contract_list( receiver ); control.check_action_list( act.account, act.name ); } @@ -205,6 +205,9 @@ void apply_context::execute_inline( action&& a ) { EOS_ASSERT( code != nullptr, action_validate_exception, "inline action's code account ${account} does not exist", ("account", a.account) ); + bool enforce_actor_whitelist_blacklist = trx_context.enforce_whiteblacklist && control.is_producing_block(); + flat_set actors; + for( const auto& auth : a.authorization ) { auto* actor = control.db().find(auth.actor); EOS_ASSERT( actor != nullptr, action_validate_exception, @@ -212,6 +215,12 @@ void apply_context::execute_inline( action&& a ) { EOS_ASSERT( control.get_authorization_manager().find_permission(auth) != nullptr, action_validate_exception, "inline action's authorizations include a non-existent permission: ${permission}", ("permission", auth) ); + if( enforce_actor_whitelist_blacklist ) + actors.insert( auth.actor ); + } + + if( enforce_actor_whitelist_blacklist ) { + control.check_actor_list( actors ); } // No need to check authorization if: replaying irreversible blocks; contract is privileged; or, contract is calling itself. @@ -249,7 +258,10 @@ void apply_context::schedule_deferred_transaction( const uint128_t& sender_id, a EOS_ASSERT( trx.context_free_actions.size() == 0, cfa_inside_generated_tx, "context free actions are not currently allowed in generated transactions" ); trx.expiration = control.pending_block_time() + fc::microseconds(999'999); // Rounds up to nearest second (makes expiration check unnecessary) trx.set_reference_block(control.head_block_id()); // No TaPoS check necessary - control.validate_referenced_accounts( trx ); + + bool enforce_actor_whitelist_blacklist = trx_context.enforce_whiteblacklist && control.is_producing_block() + && !control.sender_avoids_whitelist_blacklist_enforcement( receiver ); + trx_context.validate_referenced_accounts( trx, enforce_actor_whitelist_blacklist ); // Charge ahead of time for the additional net usage needed to retire the deferred transaction // whether that be by successfully executing, soft failure, hard failure, or expiration. diff --git a/libraries/chain/block_header_state.cpp b/libraries/chain/block_header_state.cpp index 6e7b339c42c6e51d82a512f6522c95b4592b2207..7189073f975b743f528557b99790e2204d7a98c9 100644 --- a/libraries/chain/block_header_state.cpp +++ b/libraries/chain/block_header_state.cpp @@ -58,8 +58,6 @@ namespace eosio { namespace chain { result.blockroot_merkle = blockroot_merkle; result.blockroot_merkle.append( id ); - auto block_mroot = result.blockroot_merkle.get_root(); - result.active_schedule = active_schedule; result.pending_schedule = pending_schedule; result.dpos_proposed_irreversible_blocknum = dpos_proposed_irreversible_blocknum; @@ -143,7 +141,7 @@ namespace eosio { namespace chain { * * If the header specifies new_producers then apply them accordingly. */ - block_header_state block_header_state::next( const signed_block_header& h, bool trust )const { + block_header_state block_header_state::next( const signed_block_header& h, bool skip_validate_signee )const { EOS_ASSERT( h.timestamp != block_timestamp_type(), block_validate_exception, "", ("h",h) ); EOS_ASSERT( h.header_extensions.size() == 0, block_validate_exception, "no supported extensions" ); @@ -178,9 +176,8 @@ namespace eosio { namespace chain { result.id = result.header.id(); // ASSUMPTION FROM controller_impl::apply_block = all untrusted blocks will have their signatures pre-validated here - if( !trust ) { - EOS_ASSERT( result.block_signing_key == result.signee(), wrong_signing_key, "block not signed by expected key", - ("result.block_signing_key", result.block_signing_key)("signee", result.signee() ) ); + if( !skip_validate_signee ) { + result.verify_signee( result.signee() ); } return result; @@ -236,6 +233,11 @@ namespace eosio { namespace chain { return fc::crypto::public_key( header.producer_signature, sig_digest(), true ); } + void block_header_state::verify_signee( const public_key_type& signee )const { + EOS_ASSERT( block_signing_key == signee, wrong_signing_key, "block not signed by expected key", + ("block_signing_key", block_signing_key)( "signee", signee ) ); + } + void block_header_state::add_confirmation( const header_confirmation& conf ) { for( const auto& c : confirmations ) EOS_ASSERT( c.producer != conf.producer, producer_double_confirm, "block already confirmed by this producer" ); diff --git a/libraries/chain/block_state.cpp b/libraries/chain/block_state.cpp index f62da8655df0972659c8f9728b87180c39d9b12b..b483477595148dfca528331c3de8407cd7c9a328 100644 --- a/libraries/chain/block_state.cpp +++ b/libraries/chain/block_state.cpp @@ -10,9 +10,9 @@ namespace eosio { namespace chain { static_cast(*block) = header; } - block_state::block_state( const block_header_state& prev, signed_block_ptr b, bool trust ) - :block_header_state( prev.next( *b, trust )), block( move(b) ) - { } + block_state::block_state( const block_header_state& prev, signed_block_ptr b, bool skip_validate_signee ) + :block_header_state( prev.next( *b, skip_validate_signee )), block( move(b) ) + { } diff --git a/libraries/chain/controller.cpp b/libraries/chain/controller.cpp index 41e9d551728d786467e863a9ef6845d17238ea08..4d980d5100ad9c6cc642ae0cc7329c6312d6ec43 100644 --- a/libraries/chain/controller.cpp +++ b/libraries/chain/controller.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -20,10 +21,11 @@ #include #include #include - #include -#include +#include +#include + namespace eosio { namespace chain { @@ -133,6 +135,7 @@ struct controller_impl { optional subjective_cpu_leeway; bool trusted_producer_light_validation = false; uint32_t snapshot_head_block = 0; + optional thread_pool; typedef pair handler_key; map< account_name, map > apply_handlers; @@ -144,6 +147,14 @@ struct controller_impl { */ map unapplied_transactions; + // async on thread_pool and return future + template + auto async_thread_pool( F&& f ) { + auto task = std::make_shared>( std::forward( f ) ); + boost::asio::post( *thread_pool, [task]() { (*task)(); } ); + return task->get_future(); + } + void pop_block() { auto prev = fork_db.get_block( head->header.previous ); EOS_ASSERT( prev, block_validate_exception, "attempt to pop beyond last irreversible block" ); @@ -296,22 +307,25 @@ struct controller_impl { } } - void replay() { + void replay(std::function shutdown) { auto blog_head = blog.read_head(); auto blog_head_time = blog_head->timestamp.to_time_point(); replaying = true; replay_head_time = blog_head_time; - ilog( "existing block log, attempting to replay ${n} blocks", ("n",blog_head->block_num()) ); + auto start_block_num = head->block_num + 1; + ilog( "existing block log, attempting to replay from ${s} to ${n} blocks", + ("s", start_block_num)("n", blog_head->block_num()) ); auto start = fc::time_point::now(); while( auto next = blog.read_block_by_num( head->block_num + 1 ) ) { - self.push_block( next, controller::block_status::irreversible ); + replay_push_block( next, controller::block_status::irreversible ); if( next->block_num() % 100 == 0 ) { std::cerr << std::setw(10) << next->block_num() << " of " << blog_head->block_num() <<"\r"; + if( shutdown() ) break; } } std::cerr<< "\n"; - ilog( "${n} blocks replayed", ("n", head->block_num) ); + ilog( "${n} blocks replayed", ("n", head->block_num - start_block_num) ); // if the irreverible log is played without undo sessions enabled, we need to sync the // revision ordinal to the appropriate expected value here. @@ -321,46 +335,54 @@ struct controller_impl { int rev = 0; while( auto obj = reversible_blocks.find(head->block_num+1) ) { ++rev; - self.push_block( obj->get_block(), controller::block_status::validated ); + replay_push_block( obj->get_block(), controller::block_status::validated ); } ilog( "${n} reversible blocks replayed", ("n",rev) ); auto end = fc::time_point::now(); ilog( "replayed ${n} blocks in ${duration} seconds, ${mspb} ms/block", - ("n", head->block_num)("duration", (end-start).count()/1000000) - ("mspb", ((end-start).count()/1000.0)/head->block_num) ); + ("n", head->block_num - start_block_num)("duration", (end-start).count()/1000000) + ("mspb", ((end-start).count()/1000.0)/(head->block_num-start_block_num)) ); replaying = false; replay_head_time.reset(); } - void init(const snapshot_reader_ptr& snapshot) { + void init(std::function shutdown, const snapshot_reader_ptr& snapshot) { + thread_pool.emplace( conf.thread_pool_size ); + + bool report_integrity_hash = !!snapshot; if (snapshot) { - EOS_ASSERT(!head, fork_database_exception, ""); + EOS_ASSERT( !head, fork_database_exception, "" ); snapshot->validate(); - read_from_snapshot(snapshot); + read_from_snapshot( snapshot ); auto end = blog.read_head(); if( !end ) { - blog.reset(conf.genesis, signed_block_ptr(), head->block_num + 1); - } else if ( end->block_num() > head->block_num) { - replay(); + blog.reset( conf.genesis, signed_block_ptr(), head->block_num + 1 ); + } else if( end->block_num() > head->block_num ) { + replay( shutdown ); } else { - EOS_ASSERT(end->block_num() == head->block_num, fork_database_exception, - "Block log is provided with snapshot but does not contain the head block from the snapshot"); + EOS_ASSERT( end->block_num() == head->block_num, fork_database_exception, + "Block log is provided with snapshot but does not contain the head block from the snapshot" ); + } + } else { + if( !head ) { + initialize_fork_db(); // set head to genesis state } - } else if( !head ) { - initialize_fork_db(); // set head to genesis state auto end = blog.read_head(); - if( end && end->block_num() > 1 ) { - replay(); - } else if( !end ) { + if( !end ) { blog.reset( conf.genesis, head->block ); + } else if( end->block_num() > head->block_num ) { + replay( shutdown ); + report_integrity_hash = true; } } + if( shutdown() ) return; + const auto& ubi = reversible_blocks.get_index(); auto objitr = ubi.rbegin(); if( objitr != ubi.rend() ) { @@ -386,7 +408,7 @@ struct controller_impl { db.undo(); } - if( snapshot ) { + if( report_integrity_hash ) { const auto hash = calculate_integrity_hash(); ilog( "database initialized with hash: ${hash}", ("hash", hash) ); } @@ -396,6 +418,11 @@ struct controller_impl { ~controller_impl() { pending.reset(); + if( thread_pool ) { + thread_pool->join(); + thread_pool->stop(); + } + db.flush(); reversible_blocks.flush(); } @@ -675,7 +702,7 @@ struct controller_impl { try { if (add_to_fork_db) { pending->_pending_block_state->validated = true; - auto new_bsp = fork_db.add(pending->_pending_block_state); + auto new_bsp = fork_db.add(pending->_pending_block_state, true); emit(self.accepted_block_header, pending->_pending_block_state); head = fork_db.head(); EOS_ASSERT(new_bsp == head, fork_database_exception, "committed block did not become the new head in fork database"); @@ -724,7 +751,10 @@ struct controller_impl { fc::time_point start, uint32_t& cpu_time_to_bill_us, // only set on failure uint32_t billed_cpu_time_us, - bool explicit_billed_cpu_time = false ) { + bool explicit_billed_cpu_time = false, + bool enforce_whiteblacklist = true + ) + { signed_transaction etrx; // Deliver onerror action containing the failed deferred transaction directly back to the sender. etrx.actions.emplace_back( vector{{gtrx.sender, config::active_name}}, @@ -736,6 +766,7 @@ struct controller_impl { trx_context.deadline = deadline; trx_context.explicit_billed_cpu_time = explicit_billed_cpu_time; trx_context.billed_cpu_time_us = billed_cpu_time_us; + trx_context.enforce_whiteblacklist = enforce_whiteblacklist; transaction_trace_ptr trace = trx_context.trace; try { trx_context.init_for_implicit_trx(); @@ -854,9 +885,15 @@ struct controller_impl { trx_context.deadline = deadline; trx_context.explicit_billed_cpu_time = explicit_billed_cpu_time; trx_context.billed_cpu_time_us = billed_cpu_time_us; + trx_context.enforce_whiteblacklist = gtrx.sender.empty() ? true : !sender_avoids_whitelist_blacklist_enforcement( gtrx.sender ); trace = trx_context.trace; try { trx_context.init_for_deferred_trx( gtrx.published ); + + if( trx_context.enforce_whiteblacklist && pending->_block_status == controller::block_status::incomplete ) { + check_actor_list( trx_context.bill_to_accounts ); // Assumes bill_to_accounts is the set of actors authorizing the transaction + } + trx_context.exec(); trx_context.finalize(); // Automatically rounds up network and CPU usage in trace and bills payers if successful @@ -890,8 +927,10 @@ struct controller_impl { if( gtrx.sender != account_name() && !failure_is_subjective(*trace->except)) { // Attempt error handling for the generated transaction. - dlog("${detail}", ("detail", trace->except->to_detail_string())); - auto error_trace = apply_onerror( gtrx, deadline, trx_context.pseudo_start, cpu_time_to_bill_us, billed_cpu_time_us, explicit_billed_cpu_time ); + + auto error_trace = apply_onerror( gtrx, deadline, trx_context.pseudo_start, + cpu_time_to_bill_us, billed_cpu_time_us, explicit_billed_cpu_time, + trx_context.enforce_whiteblacklist ); error_trace->failed_dtrx_trace = trace; trace = error_trace; if( !trace->except_ptr ) { @@ -986,7 +1025,7 @@ struct controller_impl { try { if( trx->implicit ) { trx_context.init_for_implicit_trx(); - trx_context.can_subjectively_fail = false; + trx_context.enforce_whiteblacklist = false; } else { bool skip_recording = replay_head_time && (time_point(trx->trx.expiration) <= *replay_head_time); trx_context.init_for_input_trx( trx->packed_trx.get_unprunable_size(), @@ -995,11 +1034,6 @@ struct controller_impl { skip_recording); } - if( trx_context.can_subjectively_fail && pending->_block_status == controller::block_status::incomplete ) { - check_actor_list( trx_context.bill_to_accounts ); // Assumes bill_to_accounts is the set of actors authorizing the transaction - } - - trx_context.delay = fc::seconds(trx->trx.delay_sec); if( !self.skip_auth_check() && !trx->implicit ) { @@ -1164,14 +1198,32 @@ struct controller_impl { auto producer_block_id = b->id(); start_block( b->timestamp, b->confirmed, s , producer_block_id); + std::vector packed_transactions; + packed_transactions.reserve( b->transactions.size() ); + for( const auto& receipt : b->transactions ) { + if( receipt.trx.contains()) { + auto& pt = receipt.trx.get(); + auto mtrx = std::make_shared( pt ); + if( !self.skip_auth_check() ) { + std::weak_ptr mtrx_wp = mtrx; + mtrx->signing_keys_future = async_thread_pool( [chain_id = this->chain_id, mtrx_wp]() { + auto mtrx = mtrx_wp.lock(); + return mtrx ? + std::make_pair( chain_id, mtrx->trx.get_signature_keys( chain_id ) ) : + std::make_pair( chain_id, decltype( mtrx->trx.get_signature_keys( chain_id ) ){} ); + } ); + } + packed_transactions.emplace_back( std::move( mtrx ) ); + } + } + transaction_trace_ptr trace; + size_t packed_idx = 0; for( const auto& receipt : b->transactions ) { auto num_pending_receipts = pending->_pending_block_state->block->transactions.size(); if( receipt.trx.contains() ) { - auto& pt = receipt.trx.get(); - auto mtrx = std::make_shared(pt); - trace = push_transaction( mtrx, fc::time_point::maximum(), receipt.cpu_usage_us, true ); + trace = push_transaction( packed_transactions.at(packed_idx++), fc::time_point::maximum(), receipt.cpu_usage_us, true ); } else if( receipt.trx.contains() ) { trace = push_scheduled_transaction( receipt.trx.get(), fc::time_point::maximum(), receipt.cpu_usage_us, true ); } else { @@ -1225,19 +1277,38 @@ struct controller_impl { } } FC_CAPTURE_AND_RETHROW() } /// apply_block + std::future create_block_state_future( const signed_block_ptr& b ) { + EOS_ASSERT( b, block_validate_exception, "null block" ); + + auto id = b->id(); - void push_block( const signed_block_ptr& b, controller::block_status s ) { + // no reason for a block_state if fork_db already knows about block + auto existing = fork_db.get_block( id ); + EOS_ASSERT( !existing, fork_database_exception, "we already know about this block: ${id}", ("id", id) ); + + auto prev = fork_db.get_block( b->previous ); + EOS_ASSERT( prev, unlinkable_block_exception, "unlinkable block ${id}", ("id", id)("previous", b->previous) ); + + return async_thread_pool( [b, prev]() { + const bool skip_validate_signee = false; + return std::make_shared( *prev, move( b ), skip_validate_signee ); + } ); + } + + void push_block( std::future& block_state_future ) { + controller::block_status s = controller::block_status::complete; EOS_ASSERT(!pending, block_validate_exception, "it is not valid to push a block when there is a pending block"); auto reset_prod_light_validation = fc::make_scoped_exit([old_value=trusted_producer_light_validation, this]() { trusted_producer_light_validation = old_value; }); try { - EOS_ASSERT( b, block_validate_exception, "trying to push empty block" ); - EOS_ASSERT( s != controller::block_status::incomplete, block_validate_exception, "invalid block status for a completed block" ); + block_state_ptr new_header_state = block_state_future.get(); + auto& b = new_header_state->block; emit( self.pre_accepted_block, b ); - bool trust = !conf.force_all_checks && (s == controller::block_status::irreversible || s == controller::block_status::validated); - auto new_header_state = fork_db.add( b, trust ); + + fork_db.add( new_header_state, false ); + if (conf.trusted_producers.count(b->producer)) { trusted_producer_light_validation = true; }; @@ -1247,6 +1318,29 @@ struct controller_impl { maybe_switch_forks( s ); } + } FC_LOG_AND_RETHROW( ) + } + + void replay_push_block( const signed_block_ptr& b, controller::block_status s ) { + self.validate_db_available_size(); + self.validate_reversible_available_size(); + + EOS_ASSERT(!pending, block_validate_exception, "it is not valid to push a block when there is a pending block"); + + try { + EOS_ASSERT( b, block_validate_exception, "trying to push empty block" ); + EOS_ASSERT( (s == controller::block_status::irreversible || s == controller::block_status::validated), + block_validate_exception, "invalid block status for replay" ); + emit( self.pre_accepted_block, b ); + const bool skip_validate_signee = !conf.force_all_checks; + auto new_header_state = fork_db.add( b, skip_validate_signee ); + + emit( self.accepted_block_header, new_header_state ); + + if ( read_mode != db_read_mode::IRREVERSIBLE ) { + maybe_switch_forks( s ); + } + // on replay irreversible is not emitted by fork database, so emit it explicitly here if( s == controller::block_status::irreversible ) emit( self.irreversible_block, new_header_state ); @@ -1254,16 +1348,7 @@ struct controller_impl { } FC_LOG_AND_RETHROW( ) } - void push_confirmation( const header_confirmation& c ) { - EOS_ASSERT(!pending, block_validate_exception, "it is not valid to push a confirmation when there is a pending block"); - fork_db.add( c ); - emit( self.accepted_confirmation, c ); - if ( read_mode != db_read_mode::IRREVERSIBLE ) { - maybe_switch_forks(); - } - } - - void maybe_switch_forks( controller::block_status s = controller::block_status::complete ) { + void maybe_switch_forks( controller::block_status s ) { auto new_head = fork_db.head(); if( new_head->header.previous == head->id ) { @@ -1282,13 +1367,13 @@ struct controller_impl { auto branches = fork_db.fetch_branch_from( new_head->id, head->id ); for( auto itr = branches.second.begin(); itr != branches.second.end(); ++itr ) { - fork_db.mark_in_current_chain( *itr , false ); + fork_db.mark_in_current_chain( *itr, false ); pop_block(); } EOS_ASSERT( self.head_block_id() == branches.second.back()->header.previous, fork_database_exception, - "loss of sync between fork_db and chainbase during fork switch" ); // _should_ never fail + "loss of sync between fork_db and chainbase during fork switch" ); // _should_ never fail - for( auto ritr = branches.first.rbegin(); ritr != branches.first.rend(); ++ritr) { + for( auto ritr = branches.first.rbegin(); ritr != branches.first.rend(); ++ritr ) { optional except; try { apply_block( (*ritr)->block, (*ritr)->validated ? controller::block_status::validated : controller::block_status::complete ); @@ -1298,7 +1383,7 @@ struct controller_impl { } catch (const fc::exception& e) { except = e; } if (except) { - elog("exception thrown while switching forks ${e}", ("e",except->to_detail_string())); + elog("exception thrown while switching forks ${e}", ("e", except->to_detail_string())); // ritr currently points to the block that threw // if we mark it invalid it will automatically remove all forks built off it. @@ -1308,11 +1393,11 @@ struct controller_impl { // ritr base is a forward itr to the last block successfully applied auto applied_itr = ritr.base(); for( auto itr = applied_itr; itr != branches.first.end(); ++itr ) { - fork_db.mark_in_current_chain( *itr , false ); + fork_db.mark_in_current_chain( *itr, false ); pop_block(); } EOS_ASSERT( self.head_block_id() == branches.second.back()->header.previous, fork_database_exception, - "loss of sync between fork_db and chainbase during fork switch reversal" ); // _should_ never fail + "loss of sync between fork_db and chainbase during fork switch reversal" ); // _should_ never fail // re-apply good blocks for( auto ritr = branches.second.rbegin(); ritr != branches.second.rend(); ++ritr ) { @@ -1323,7 +1408,7 @@ struct controller_impl { throw *except; } // end if exception } /// end for each block in branch - ilog("successfully switched fork to new head ${new_head_id}", ("new_head_id", new_head->id)); + ilog("successfully switched fork to new head ${new_head_id}", ("new_head_id", new_head->id) ); } } /// push_block @@ -1458,28 +1543,97 @@ struct controller_impl { } } + bool sender_avoids_whitelist_blacklist_enforcement( account_name sender )const { + if( conf.sender_bypass_whiteblacklist.size() > 0 && + ( conf.sender_bypass_whiteblacklist.find( sender ) != conf.sender_bypass_whiteblacklist.end() ) ) + { + return true; + } + + return false; + } void check_actor_list( const flat_set& actors )const { + if( actors.size() == 0 ) return; + if( conf.actor_whitelist.size() > 0 ) { - vector excluded; - excluded.reserve( actors.size() ); - set_difference( actors.begin(), actors.end(), - conf.actor_whitelist.begin(), conf.actor_whitelist.end(), - std::back_inserter(excluded) ); - EOS_ASSERT( excluded.size() == 0, actor_whitelist_exception, + // throw if actors is not a subset of whitelist + const auto& whitelist = conf.actor_whitelist; + bool is_subset = true; + + // quick extents check, then brute force the check actors + if (*actors.cbegin() >= *whitelist.cbegin() && *actors.crbegin() <= *whitelist.crbegin() ) { + auto lower_bound = whitelist.cbegin(); + for (const auto& actor: actors) { + lower_bound = std::lower_bound(lower_bound, whitelist.cend(), actor); + + // if the actor is not found, this is not a subset + if (lower_bound == whitelist.cend() || *lower_bound != actor ) { + is_subset = false; + break; + } + + // if the actor was found, we are guaranteed that other actors are either not present in the whitelist + // or will be present in the range defined as [next actor,end) + lower_bound = std::next(lower_bound); + } + } else { + is_subset = false; + } + + // helper lambda to lazily calculate the actors for error messaging + static auto generate_missing_actors = [](const flat_set& actors, const flat_set& whitelist) -> vector { + vector excluded; + excluded.reserve( actors.size() ); + set_difference( actors.begin(), actors.end(), + whitelist.begin(), whitelist.end(), + std::back_inserter(excluded) ); + return excluded; + }; + + EOS_ASSERT( is_subset, actor_whitelist_exception, "authorizing actor(s) in transaction are not on the actor whitelist: ${actors}", - ("actors", excluded) + ("actors", generate_missing_actors(actors, whitelist)) ); } else if( conf.actor_blacklist.size() > 0 ) { - vector blacklisted; - blacklisted.reserve( actors.size() ); - set_intersection( actors.begin(), actors.end(), - conf.actor_blacklist.begin(), conf.actor_blacklist.end(), - std::back_inserter(blacklisted) - ); - EOS_ASSERT( blacklisted.size() == 0, actor_blacklist_exception, + // throw if actors intersects blacklist + const auto& blacklist = conf.actor_blacklist; + bool intersects = false; + + // quick extents check then brute force check actors + if( *actors.cbegin() <= *blacklist.crbegin() && *actors.crbegin() >= *blacklist.cbegin() ) { + auto lower_bound = blacklist.cbegin(); + for (const auto& actor: actors) { + lower_bound = std::lower_bound(lower_bound, blacklist.cend(), actor); + + // if the lower bound in the blacklist is at the end, all other actors are guaranteed to + // not exist in the blacklist + if (lower_bound == blacklist.cend()) { + break; + } + + // if the lower bound of an actor IS the actor, then we have an intersection + if (*lower_bound == actor) { + intersects = true; + break; + } + } + } + + // helper lambda to lazily calculate the actors for error messaging + static auto generate_blacklisted_actors = [](const flat_set& actors, const flat_set& blacklist) -> vector { + vector blacklisted; + blacklisted.reserve( actors.size() ); + set_intersection( actors.begin(), actors.end(), + blacklist.begin(), blacklist.end(), + std::back_inserter(blacklisted) + ); + return blacklisted; + }; + + EOS_ASSERT( !intersects, actor_blacklist_exception, "authorizing actor(s) in transaction are on the actor blacklist: ${actors}", - ("actors", blacklisted) + ("actors", generate_blacklisted_actors(actors, blacklist)) ); } } @@ -1590,12 +1744,12 @@ void controller::add_indices() { my->add_indices(); } -void controller::startup( const snapshot_reader_ptr& snapshot ) { +void controller::startup( std::function shutdown, const snapshot_reader_ptr& snapshot ) { my->head = my->fork_db.head(); if( !my->head ) { elog( "No head block in fork db, perhaps we need to replay" ); } - my->init(snapshot); + my->init(shutdown, snapshot); } const chainbase::database& controller::db()const { return my->db; } @@ -1629,15 +1783,14 @@ void controller::abort_block() { my->abort_block(); } -void controller::push_block( const signed_block_ptr& b, block_status s ) { - validate_db_available_size(); - validate_reversible_available_size(); - my->push_block( b, s ); +std::future controller::create_block_state_future( const signed_block_ptr& b ) { + return my->create_block_state_future( b ); } -void controller::push_confirmation( const header_confirmation& c ) { +void controller::push_block( std::future& block_state_future ) { validate_db_available_size(); - my->push_confirmation( c ); + validate_reversible_available_size(); + my->push_block( block_state_future ); } transaction_trace_ptr controller::push_transaction( const transaction_metadata_ptr& trx, fc::time_point deadline, uint32_t billed_cpu_time_us ) { @@ -1997,6 +2150,14 @@ vector controller::get_scheduled_transactions() const { return result; } +bool controller::sender_avoids_whitelist_blacklist_enforcement( account_name sender )const { + return my->sender_avoids_whitelist_blacklist_enforcement( sender ); +} + +void controller::check_actor_list( const flat_set& actors )const { + my->check_actor_list( actors ); +} + void controller::check_contract_list( account_name code )const { my->check_contract_list( code ); } @@ -2019,32 +2180,6 @@ bool controller::is_ram_billing_in_notify_allowed()const { return !is_producing_block() || my->conf.allow_ram_billing_in_notify; } -void controller::validate_referenced_accounts( const transaction& trx )const { - for( const auto& a : trx.context_free_actions ) { - auto* code = my->db.find(a.account); - EOS_ASSERT( code != nullptr, transaction_exception, - "action's code account '${account}' does not exist", ("account", a.account) ); - EOS_ASSERT( a.authorization.size() == 0, transaction_exception, - "context-free actions cannot have authorizations" ); - } - bool one_auth = false; - for( const auto& a : trx.actions ) { - auto* code = my->db.find(a.account); - EOS_ASSERT( code != nullptr, transaction_exception, - "action's code account '${account}' does not exist", ("account", a.account) ); - for( const auto& auth : a.authorization ) { - one_auth = true; - auto* actor = my->db.find(auth.actor); - EOS_ASSERT( actor != nullptr, transaction_exception, - "action's authorizing actor '${account}' does not exist", ("account", auth.actor) ); - EOS_ASSERT( my->authorization.find_permission(auth) != nullptr, transaction_exception, - "action's authorizations include a non-existent permission: {permission}", - ("permission", auth) ); - } - } - EOS_ASSERT( one_auth, tx_no_auths, "transaction must have at least one authorization" ); -} - void controller::validate_expiration( const transaction& trx )const { try { const auto& chain_configuration = get_global_properties().configuration; diff --git a/libraries/chain/eosio_contract.cpp b/libraries/chain/eosio_contract.cpp index 33a123981a15bf4e9463257b1f5c3d4d615cc29f..e41fe815834b92dbf610a7cea9ef40fe15097912 100644 --- a/libraries/chain/eosio_contract.cpp +++ b/libraries/chain/eosio_contract.cpp @@ -57,7 +57,7 @@ void validate_authority_precondition( const apply_context& context, const author } } - if( context.control.is_producing_block() ) { + if( context.trx_context.enforce_whiteblacklist && context.control.is_producing_block() ) { for( const auto& p : auth.keys ) { context.control.check_key_list( p.key ); } @@ -282,7 +282,7 @@ void apply_eosio_deleteauth(apply_context& context) { const auto& index = db.get_index(); auto range = index.equal_range(boost::make_tuple(remove.account, remove.permission)); EOS_ASSERT(range.first == range.second, action_validate_exception, - "Cannot delete a linked authority. Unlink the authority first. This authority is linked to ${code}::${type}.", + "Cannot delete a linked authority. Unlink the authority first. This authority is linked to ${code}::${type}.", ("code", string(range.first->code))("type", string(range.first->message_type))); } diff --git a/libraries/chain/fork_database.cpp b/libraries/chain/fork_database.cpp index c56ed0add05ac1c7dfa8635ebf2e111f43376bf7..52b49fff4494d15cde8cae0d842d577c6e0956a9 100644 --- a/libraries/chain/fork_database.cpp +++ b/libraries/chain/fork_database.cpp @@ -123,7 +123,16 @@ namespace eosio { namespace chain { } } - block_state_ptr fork_database::add( block_state_ptr n ) { + block_state_ptr fork_database::add( const block_state_ptr& n, bool skip_validate_previous ) { + EOS_ASSERT( n, fork_database_exception, "attempt to add null block state" ); + EOS_ASSERT( my->head, fork_db_block_not_found, "no head block set" ); + + if( !skip_validate_previous ) { + auto prior = my->index.find( n->block->previous ); + EOS_ASSERT( prior != my->index.end(), unlinkable_block_exception, + "unlinkable block", ("id", n->block->id())("previous", n->block->previous) ); + } + auto inserted = my->index.insert(n); EOS_ASSERT( inserted.second, fork_database_exception, "duplicate block added?" ); @@ -139,7 +148,7 @@ namespace eosio { namespace chain { return n; } - block_state_ptr fork_database::add( signed_block_ptr b, bool trust ) { + block_state_ptr fork_database::add( signed_block_ptr b, bool skip_validate_signee ) { EOS_ASSERT( b, fork_database_exception, "attempt to add null block" ); EOS_ASSERT( my->head, fork_db_block_not_found, "no head block set" ); @@ -150,9 +159,9 @@ namespace eosio { namespace chain { auto prior = by_id_idx.find( b->previous ); EOS_ASSERT( prior != by_id_idx.end(), unlinkable_block_exception, "unlinkable block", ("id", string(b->id()))("previous", string(b->previous)) ); - auto result = std::make_shared( **prior, move(b), trust ); + auto result = std::make_shared( **prior, move(b), skip_validate_signee ); EOS_ASSERT( result, fork_database_exception , "fail to add new block state" ); - return add(result); + return add(result, true); } const block_state_ptr& fork_database::head()const { return my->head; } diff --git a/libraries/chain/include/eosio/chain/apply_context.hpp b/libraries/chain/include/eosio/chain/apply_context.hpp index a253d950358878536462f9c8464a258a3bea8be1..f0662ca5c050ff523c2699044d0f5fce3e3f6a7c 100644 --- a/libraries/chain/include/eosio/chain/apply_context.hpp +++ b/libraries/chain/include/eosio/chain/apply_context.hpp @@ -575,12 +575,6 @@ class apply_context { void add_ram_usage( account_name account, int64_t ram_delta ); void finalize_trace( action_trace& trace, const fc::time_point& start ); - private: - - void validate_referenced_accounts( const transaction& t )const; - void validate_expiration( const transaction& t )const; - - /// Fields: public: diff --git a/libraries/chain/include/eosio/chain/authority_checker.hpp b/libraries/chain/include/eosio/chain/authority_checker.hpp index 5f1fdfbfb764e76cfe08dc8b5468403cf4aede7f..068cc5a9137b241e4403fa9daf130c5740e5e1b7 100644 --- a/libraries/chain/include/eosio/chain/authority_checker.hpp +++ b/libraries/chain/include/eosio/chain/authority_checker.hpp @@ -7,8 +7,7 @@ #include #include #include - -#include +#include #include @@ -148,11 +147,11 @@ namespace detail { bool all_keys_used() const { return boost::algorithm::all_of_equal(_used_keys, true); } flat_set used_keys() const { - auto range = utilities::filter_data_by_marker(provided_keys, _used_keys, true); + auto range = filter_data_by_marker(provided_keys, _used_keys, true); return {range.begin(), range.end()}; } flat_set unused_keys() const { - auto range = utilities::filter_data_by_marker(provided_keys, _used_keys, false); + auto range = filter_data_by_marker(provided_keys, _used_keys, false); return {range.begin(), range.end()}; } diff --git a/libraries/chain/include/eosio/chain/block_header_state.hpp b/libraries/chain/include/eosio/chain/block_header_state.hpp index ecd272353d41c34ecbd1c85f391c1f19452eeb24..c318843d5df9e6d25c0d392fbe0561d7780c5c81 100644 --- a/libraries/chain/include/eosio/chain/block_header_state.hpp +++ b/libraries/chain/include/eosio/chain/block_header_state.hpp @@ -1,6 +1,7 @@ #pragma once #include #include +#include namespace eosio { namespace chain { @@ -51,6 +52,7 @@ struct block_header_state { digest_type sig_digest()const; void sign( const std::function& signer ); public_key_type signee()const; + void verify_signee(const public_key_type& signee)const; }; diff --git a/libraries/chain/include/eosio/chain/block_state.hpp b/libraries/chain/include/eosio/chain/block_state.hpp index 73602023a4227f17a0f13e41c79bf9be1d39017d..6870d04f5b20bbac89e7a4b609a0556545a20460 100644 --- a/libraries/chain/include/eosio/chain/block_state.hpp +++ b/libraries/chain/include/eosio/chain/block_state.hpp @@ -12,8 +12,8 @@ namespace eosio { namespace chain { struct block_state : public block_header_state { - block_state( const block_header_state& cur ):block_header_state(cur){} - block_state( const block_header_state& prev, signed_block_ptr b, bool trust = false ); + explicit block_state( const block_header_state& cur ):block_header_state(cur){} + block_state( const block_header_state& prev, signed_block_ptr b, bool skip_validate_signee ); block_state( const block_header_state& prev, block_timestamp_type when ); block_state() = default; diff --git a/libraries/chain/include/eosio/chain/chain_config.hpp b/libraries/chain/include/eosio/chain/chain_config.hpp index 7f62ff111f994954cb5e8a9fb24a0118a45b0f0b..f51a8b238f6523777160c105bc94261b10bc68b4 100644 --- a/libraries/chain/include/eosio/chain/chain_config.hpp +++ b/libraries/chain/include/eosio/chain/chain_config.hpp @@ -60,10 +60,50 @@ struct chain_config { << "Max Inline Action Depth: " << c.max_inline_action_depth << ", " << "Max Authority Depth: " << c.max_authority_depth << "\n"; } -}; - bool operator==(const chain_config& a, const chain_config& b); -inline bool operator!=(const chain_config& a, const chain_config& b) { return !(a == b); } + friend inline bool operator ==( const chain_config& lhs, const chain_config& rhs ) { + return std::tie( lhs.max_block_net_usage, + lhs.target_block_net_usage_pct, + lhs.max_transaction_net_usage, + lhs.base_per_transaction_net_usage, + lhs.net_usage_leeway, + lhs.context_free_discount_net_usage_num, + lhs.context_free_discount_net_usage_den, + lhs.max_block_cpu_usage, + lhs.target_block_cpu_usage_pct, + lhs.max_transaction_cpu_usage, + lhs.max_transaction_cpu_usage, + lhs.max_transaction_lifetime, + lhs.deferred_trx_expiration_window, + lhs.max_transaction_delay, + lhs.max_inline_action_size, + lhs.max_inline_action_depth, + lhs.max_authority_depth + ) + == + std::tie( rhs.max_block_net_usage, + rhs.target_block_net_usage_pct, + rhs.max_transaction_net_usage, + rhs.base_per_transaction_net_usage, + rhs.net_usage_leeway, + rhs.context_free_discount_net_usage_num, + rhs.context_free_discount_net_usage_den, + rhs.max_block_cpu_usage, + rhs.target_block_cpu_usage_pct, + rhs.max_transaction_cpu_usage, + rhs.max_transaction_cpu_usage, + rhs.max_transaction_lifetime, + rhs.deferred_trx_expiration_window, + rhs.max_transaction_delay, + rhs.max_inline_action_size, + rhs.max_inline_action_depth, + rhs.max_authority_depth + ); + }; + + friend inline bool operator !=( const chain_config& lhs, const chain_config& rhs ) { return !(lhs == rhs); } + +}; } } // namespace eosio::chain diff --git a/libraries/chain/include/eosio/chain/config.hpp b/libraries/chain/include/eosio/chain/config.hpp index c0e9806319e3aa08b18028a9dce058c14d1cf38a..307b36aab00ebd6c66dd0cdbe777d39dd736e965 100644 --- a/libraries/chain/include/eosio/chain/config.hpp +++ b/libraries/chain/include/eosio/chain/config.hpp @@ -79,6 +79,7 @@ const static uint32_t default_max_trx_delay = 45*24*3600; // const static uint32_t default_max_inline_action_size = 4 * 1024; // 4 KB const static uint16_t default_max_inline_action_depth = 4; const static uint16_t default_max_auth_depth = 6; +const static uint16_t default_controller_thread_pool_size = 2; const static uint32_t min_net_usage_delta_between_base_and_max_for_trx = 10*1024; // Should be large enough to allow recovery from badly set blockchain parameters without a hard fork diff --git a/libraries/chain/include/eosio/chain/contract_table_objects.hpp b/libraries/chain/include/eosio/chain/contract_table_objects.hpp index b342834082341fea0606a990f0b781d20e906087..8be51a98daf874742916412c1136e43665f9908a 100644 --- a/libraries/chain/include/eosio/chain/contract_table_objects.hpp +++ b/libraries/chain/include/eosio/chain/contract_table_objects.hpp @@ -131,14 +131,14 @@ namespace eosio { namespace chain { typedef secondary_index::index_index index256_index; struct soft_double_less { - bool operator()( const float64_t& lhs, const float64_t& rhs )const { - return f64_lt(lhs, rhs); + bool operator()( const float64_t& lhs, const float64_t& rhs ) const { + return f64_lt( lhs, rhs ); } }; struct soft_long_double_less { - bool operator()( const float128_t lhs, const float128_t& rhs )const { - return f128_lt(lhs, rhs); + bool operator()( const float128_t& lhs, const float128_t& rhs ) const { + return f128_lt( lhs, rhs ); } }; @@ -147,6 +147,7 @@ namespace eosio { namespace chain { * * The software double implementation is using the Berkeley softfloat library (release 3). */ + typedef secondary_index::index_object index_double_object; typedef secondary_index::index_index index_double_index; @@ -158,6 +159,65 @@ namespace eosio { namespace chain { typedef secondary_index::index_object index_long_double_object; typedef secondary_index::index_index index_long_double_index; + template + struct secondary_key_traits { + using value_type = std::enable_if_t::value, T>; + + static_assert( std::numeric_limits::is_specialized, "value_type does not have specialized numeric_limits" ); + + static constexpr value_type true_lowest() { return std::numeric_limits::lowest(); } + static constexpr value_type true_highest() { return std::numeric_limits::max(); } + }; + + template + struct secondary_key_traits> { + private: + static constexpr uint128_t max_uint128 = (static_cast(std::numeric_limits::max()) << 64) | std::numeric_limits::max(); + static_assert( std::numeric_limits::max() == max_uint128, "numeric_limits for uint128_t is not properly defined" ); + + public: + using value_type = std::array; + + static value_type true_lowest() { + value_type arr; + return arr; + } + + static value_type true_highest() { + value_type arr; + for( auto& v : arr ) { + v = std::numeric_limits::max(); + } + return arr; + } + }; + + template<> + struct secondary_key_traits { + using value_type = float64_t; + + static value_type true_lowest() { + return f64_negative_infinity(); + } + + static value_type true_highest() { + return f64_positive_infinity(); + } + }; + + template<> + struct secondary_key_traits { + using value_type = float128_t; + + static value_type true_lowest() { + return f128_negative_infinity(); + } + + static value_type true_highest() { + return f128_positive_infinity(); + } + }; + /** * helper template to map from an index type to the best tag * to use when traversing by table_id @@ -185,7 +245,7 @@ namespace config { template<> struct billable_size { static const uint64_t overhead = overhead_per_row_per_index_ram_bytes * 2; ///< overhead for 2x indices internal-key and code,scope,table - static const uint64_t value = 44 + overhead; ///< 36 bytes for constant size fields + overhead + static const uint64_t value = 44 + overhead; ///< 44 bytes for constant size fields + overhead }; template<> diff --git a/libraries/chain/include/eosio/chain/controller.hpp b/libraries/chain/include/eosio/chain/controller.hpp index ec7b53fafc0bd7810b47c598fcea896407d24c25..7e963cd10286d510434c9aa230367b282c57561c 100644 --- a/libraries/chain/include/eosio/chain/controller.hpp +++ b/libraries/chain/include/eosio/chain/controller.hpp @@ -50,6 +50,7 @@ namespace eosio { namespace chain { public: struct config { + flat_set sender_bypass_whiteblacklist; flat_set actor_whitelist; flat_set actor_blacklist; flat_set contract_whitelist; @@ -62,6 +63,7 @@ namespace eosio { namespace chain { uint64_t state_guard_size = chain::config::default_state_guard_size; uint64_t reversible_cache_size = chain::config::default_reversible_cache_size; uint64_t reversible_guard_size = chain::config::default_reversible_guard_size; + uint16_t thread_pool_size = chain::config::default_controller_thread_pool_size; bool read_only = false; bool force_all_checks = false; bool disable_replay_opts = false; @@ -89,7 +91,7 @@ namespace eosio { namespace chain { ~controller(); void add_indices(); - void startup( const snapshot_reader_ptr& snapshot = nullptr ); + void startup( std::function shutdown, const snapshot_reader_ptr& snapshot = nullptr ); /** * Starts a new pending block session upon which new transactions can @@ -139,13 +141,8 @@ namespace eosio { namespace chain { void commit_block(); void pop_block(); - void push_block( const signed_block_ptr& b, block_status s = block_status::complete ); - - /** - * Call this method when a producer confirmation is received, this might update - * the last bft irreversible block and/or cause a switch of forks - */ - void push_confirmation( const header_confirmation& c ); + std::future create_block_state_future( const signed_block_ptr& b ); + void push_block( std::future& block_state_future ); const chainbase::database& db()const; @@ -207,6 +204,8 @@ namespace eosio { namespace chain { sha256 calculate_integrity_hash()const; void write_snapshot( const snapshot_writer_ptr& snapshot )const; + bool sender_avoids_whitelist_blacklist_enforcement( account_name sender )const; + void check_actor_list( const flat_set& actors )const; void check_contract_list( account_name code )const; void check_action_list( account_name code, action_name action )const; void check_key_list( const public_key_type& key )const; @@ -219,7 +218,6 @@ namespace eosio { namespace chain { bool is_resource_greylisted(const account_name &name) const; const flat_set &get_resource_greylist() const; - void validate_referenced_accounts( const transaction& t )const; void validate_expiration( const transaction& t )const; void validate_tapos( const transaction& t )const; void validate_db_available_size() const; diff --git a/libraries/chain/include/eosio/chain/database_utils.hpp b/libraries/chain/include/eosio/chain/database_utils.hpp index e2b0c0d487f3c93ee4371d98111715ee25bc0121..eee26bce1c040b68648b14246cedf460e7fc5487 100644 --- a/libraries/chain/include/eosio/chain/database_utils.hpp +++ b/libraries/chain/include/eosio/chain/database_utils.hpp @@ -216,4 +216,3 @@ DataStream& operator >> ( DataStream& ds, float128_t& v ) { fc::raw::unpack(ds, *reinterpret_cast(&v)); return ds; } - diff --git a/libraries/chain/include/eosio/chain/exceptions.hpp b/libraries/chain/include/eosio/chain/exceptions.hpp index 2dc5e114d03207eb87fcc1fabdd47900473a6182..01a42793e946e6c593d32c67a3214880df6ef01e 100644 --- a/libraries/chain/include/eosio/chain/exceptions.hpp +++ b/libraries/chain/include/eosio/chain/exceptions.hpp @@ -439,8 +439,8 @@ namespace eosio { namespace chain { 3160007, "Invalid contract vm version" ) FC_DECLARE_DERIVED_EXCEPTION( set_exact_code, contract_exception, 3160008, "Contract is already running this version of code" ) - FC_DECLARE_DERIVED_EXCEPTION( wast_file_not_found, contract_exception, - 3160009, "No wast file found" ) + FC_DECLARE_DERIVED_EXCEPTION( wasm_file_not_found, contract_exception, + 3160009, "No wasm file found" ) FC_DECLARE_DERIVED_EXCEPTION( abi_file_not_found, contract_exception, 3160010, "No abi file found" ) diff --git a/libraries/chain/include/eosio/chain/fork_database.hpp b/libraries/chain/include/eosio/chain/fork_database.hpp index 529a43a0a05c6a9ee415f2ba58ffbab9e587c187..998157ab41aab455df231cdf9cdc15563d57a436 100644 --- a/libraries/chain/include/eosio/chain/fork_database.hpp +++ b/libraries/chain/include/eosio/chain/fork_database.hpp @@ -36,12 +36,12 @@ namespace eosio { namespace chain { */ void set( block_state_ptr s ); - /** this method will attempt to append the block to an exsting + /** this method will attempt to append the block to an existing * block_state and will return a pointer to the new block state or * throw on error. */ - block_state_ptr add( signed_block_ptr b, bool trust = false ); - block_state_ptr add( block_state_ptr next_block ); + block_state_ptr add( signed_block_ptr b, bool skip_validate_signee ); + block_state_ptr add( const block_state_ptr& next_block, bool skip_validate_previous ); void remove( const block_id_type& id ); void add( const header_confirmation& c ); diff --git a/libraries/chain/include/eosio/chain/genesis_state.hpp b/libraries/chain/include/eosio/chain/genesis_state.hpp index 9fd05a82dc6d3c13b2747c86d02b482c3f7f2dc9..7b1da43043f6455b847933ae50ce0f729561dd71 100644 --- a/libraries/chain/include/eosio/chain/genesis_state.hpp +++ b/libraries/chain/include/eosio/chain/genesis_state.hpp @@ -51,6 +51,14 @@ struct genesis_state { * This is the SHA256 serialization of the genesis_state. */ chain_id_type compute_chain_id() const; + + friend inline bool operator==( const genesis_state& lhs, const genesis_state& rhs ) { + return std::tie( lhs.initial_configuration, lhs.initial_timestamp, lhs.initial_key ) + == std::tie( rhs.initial_configuration, rhs.initial_timestamp, rhs.initial_key ); + }; + + friend inline bool operator!=( const genesis_state& lhs, const genesis_state& rhs ) { return !(lhs == rhs); } + }; } } // namespace eosio::chain diff --git a/libraries/utilities/include/eosio/utilities/parallel_markers.hpp b/libraries/chain/include/eosio/chain/parallel_markers.hpp similarity index 95% rename from libraries/utilities/include/eosio/utilities/parallel_markers.hpp rename to libraries/chain/include/eosio/chain/parallel_markers.hpp index 0d6aa5a98215a2cb345678c8a34c3bf8449435ab..c78ebdabdaed6ff0a3bb10a9da9f48301e3ff8f9 100644 --- a/libraries/utilities/include/eosio/utilities/parallel_markers.hpp +++ b/libraries/chain/include/eosio/chain/parallel_markers.hpp @@ -8,7 +8,7 @@ #include #include -namespace eosio { namespace utilities { +namespace eosio { namespace chain { /** * @brief Return values in DataRange corresponding to matching Markers @@ -39,5 +39,5 @@ DataRange filter_data_by_marker(DataRange data, MarkerRange markers, const Marke return {range.begin(), range.end()}; } -}} // namespace eosio::utilities +}} // namespace eosio::chain diff --git a/libraries/chain/include/eosio/chain/transaction_context.hpp b/libraries/chain/include/eosio/chain/transaction_context.hpp index b69a00143e9f832b43a4fedbe54e684de66a67c2..2e215f00ec2444db824896adcb3c5d9bcab6df05 100644 --- a/libraries/chain/include/eosio/chain/transaction_context.hpp +++ b/libraries/chain/include/eosio/chain/transaction_context.hpp @@ -56,6 +56,8 @@ namespace eosio { namespace chain { std::tuple max_bandwidth_billed_accounts_can_pay( bool force_elastic_limits = false )const; + void validate_referenced_accounts( const transaction& trx, bool enforce_actor_whitelist_blacklist )const; + private: friend struct controller_impl; @@ -95,7 +97,7 @@ namespace eosio { namespace chain { fc::microseconds delay; bool is_input = false; bool apply_context_free = true; - bool can_subjectively_fail = true; + bool enforce_whiteblacklist = true; fc::time_point deadline = fc::time_point::maximum(); fc::microseconds leeway = fc::microseconds(3000); diff --git a/libraries/chain/include/eosio/chain/transaction_metadata.hpp b/libraries/chain/include/eosio/chain/transaction_metadata.hpp index 44d5d008a79dad4af19d9a920a6b0c02f0f5db50..c5eb0c790f40808fcf167064eaa73a29ba0bd266 100644 --- a/libraries/chain/include/eosio/chain/transaction_metadata.hpp +++ b/libraries/chain/include/eosio/chain/transaction_metadata.hpp @@ -4,8 +4,8 @@ */ #pragma once #include -#include -#include +#include +#include namespace eosio { namespace chain { @@ -20,6 +20,7 @@ class transaction_metadata { signed_transaction trx; packed_transaction packed_trx; optional>> signing_keys; + std::future>> signing_keys_future; bool accepted = false; bool implicit = false; bool scheduled = false; @@ -39,8 +40,16 @@ class transaction_metadata { } const flat_set& recover_keys( const chain_id_type& chain_id ) { - if( !signing_keys || signing_keys->first != chain_id ) // Unlikely for more than one chain_id to be used in one nodeos instance - signing_keys = std::make_pair( chain_id, trx.get_signature_keys( chain_id ) ); + // Unlikely for more than one chain_id to be used in one nodeos instance + if( !signing_keys || signing_keys->first != chain_id ) { + if( signing_keys_future.valid() ) { + signing_keys = signing_keys_future.get(); + if( signing_keys->first == chain_id ) { + return signing_keys->second; + } + } + signing_keys = std::make_pair( chain_id, trx.get_signature_keys( chain_id )); + } return signing_keys->second; } diff --git a/libraries/chain/transaction.cpp b/libraries/chain/transaction.cpp index c49f76ce7710f4c81d4d80bed7874defcf1503dd..6e6639bac5282fe476c2c1c653a9ef8a8dceac82 100644 --- a/libraries/chain/transaction.cpp +++ b/libraries/chain/transaction.cpp @@ -87,7 +87,7 @@ flat_set transaction::get_signature_keys( const vector recovered_pub_keys; diff --git a/libraries/chain/transaction_context.cpp b/libraries/chain/transaction_context.cpp index 476a78d982b5eee87c10de021e8d517d14d8f450..989905ef9a004d448ff3e17f9aee48225e4ff1e8 100644 --- a/libraries/chain/transaction_context.cpp +++ b/libraries/chain/transaction_context.cpp @@ -26,7 +26,7 @@ namespace bacc = boost::accumulators; struct deadline_timer_verify { deadline_timer_verify() { //keep longest first in list. You're effectively going to take test_intervals[0]*sizeof(test_intervals[0]) - //time to do the the "calibration" + //time to do the the "calibration" int test_intervals[] = {50000, 10000, 5000, 1000, 500, 100, 50, 10}; struct sigaction act; @@ -314,7 +314,7 @@ namespace bacc = boost::accumulators; if (!control.skip_trx_checks()) { control.validate_expiration(trx); control.validate_tapos(trx); - control.validate_referenced_accounts(trx); + validate_referenced_accounts( trx, enforce_whiteblacklist && control.is_producing_block() ); } init( initial_net_usage); if (!skip_recording) @@ -615,5 +615,43 @@ namespace bacc = boost::accumulators; } } /// record_transaction + void transaction_context::validate_referenced_accounts( const transaction& trx, bool enforce_actor_whitelist_blacklist )const { + const auto& db = control.db(); + const auto& auth_manager = control.get_authorization_manager(); + + for( const auto& a : trx.context_free_actions ) { + auto* code = db.find(a.account); + EOS_ASSERT( code != nullptr, transaction_exception, + "action's code account '${account}' does not exist", ("account", a.account) ); + EOS_ASSERT( a.authorization.size() == 0, transaction_exception, + "context-free actions cannot have authorizations" ); + } + + flat_set actors; + + bool one_auth = false; + for( const auto& a : trx.actions ) { + auto* code = db.find(a.account); + EOS_ASSERT( code != nullptr, transaction_exception, + "action's code account '${account}' does not exist", ("account", a.account) ); + for( const auto& auth : a.authorization ) { + one_auth = true; + auto* actor = db.find(auth.actor); + EOS_ASSERT( actor != nullptr, transaction_exception, + "action's authorizing actor '${account}' does not exist", ("account", auth.actor) ); + EOS_ASSERT( auth_manager.find_permission(auth) != nullptr, transaction_exception, + "action's authorizations include a non-existent permission: {permission}", + ("permission", auth) ); + if( enforce_actor_whitelist_blacklist ) + actors.insert( auth.actor ); + } + } + EOS_ASSERT( one_auth, tx_no_auths, "transaction must have at least one authorization" ); + + if( enforce_actor_whitelist_blacklist ) { + control.check_actor_list( actors ); + } + } + } } /// eosio::chain diff --git a/libraries/chain/wasm_interface.cpp b/libraries/chain/wasm_interface.cpp index f03fb71f4452af207ca4686d00d5cfd34ee98019..09607b7c6b7df7f45fefeb949acf4a2cd42be37b 100644 --- a/libraries/chain/wasm_interface.cpp +++ b/libraries/chain/wasm_interface.cpp @@ -237,8 +237,8 @@ class softfloat_api : public context_aware_api { if (is_nan(b)) { return bf; } - if ( sign_bit(a) != sign_bit(b) ) { - return sign_bit(a) ? af : bf; + if ( f32_sign_bit(a) != f32_sign_bit(b) ) { + return f32_sign_bit(a) ? af : bf; } return f32_lt(a,b) ? af : bf; } @@ -251,8 +251,8 @@ class softfloat_api : public context_aware_api { if (is_nan(b)) { return bf; } - if ( sign_bit(a) != sign_bit(b) ) { - return sign_bit(a) ? bf : af; + if ( f32_sign_bit(a) != f32_sign_bit(b) ) { + return f32_sign_bit(a) ? bf : af; } return f32_lt( a, b ) ? bf : af; } @@ -404,8 +404,8 @@ class softfloat_api : public context_aware_api { return af; if (is_nan(b)) return bf; - if (sign_bit(a) != sign_bit(b)) - return sign_bit(a) ? af : bf; + if (f64_sign_bit(a) != f64_sign_bit(b)) + return f64_sign_bit(a) ? af : bf; return f64_lt( a, b ) ? af : bf; } double _eosio_f64_max( double af, double bf ) { @@ -415,8 +415,8 @@ class softfloat_api : public context_aware_api { return af; if (is_nan(b)) return bf; - if (sign_bit(a) != sign_bit(b)) - return sign_bit(a) ? bf : af; + if (f64_sign_bit(a) != f64_sign_bit(b)) + return f64_sign_bit(a) ? bf : af; return f64_lt( a, b ) ? bf : af; } double _eosio_f64_copysign( double af, double bf ) { @@ -650,32 +650,17 @@ class softfloat_api : public context_aware_api { } static bool is_nan( const float32_t f ) { - return ((f.v & 0x7FFFFFFF) > 0x7F800000); + return f32_is_nan( f ); } static bool is_nan( const float64_t f ) { - return ((f.v & 0x7FFFFFFFFFFFFFFF) > 0x7FF0000000000000); + return f64_is_nan( f ); } static bool is_nan( const float128_t& f ) { - return (((~(f.v[1]) & uint64_t( 0x7FFF000000000000 )) == 0) && (f.v[0] || ((f.v[1]) & uint64_t( 0x0000FFFFFFFFFFFF )))); - } - static float32_t to_softfloat32( float f ) { - return *reinterpret_cast(&f); - } - static float64_t to_softfloat64( double d ) { - return *reinterpret_cast(&d); - } - static float from_softfloat32( float32_t f ) { - return *reinterpret_cast(&f); - } - static double from_softfloat64( float64_t d ) { - return *reinterpret_cast(&d); + return f128_is_nan( f ); } + static constexpr uint32_t inv_float_eps = 0x4B000000; static constexpr uint64_t inv_double_eps = 0x4330000000000000; - - static bool sign_bit( float32_t f ) { return f.v >> 31; } - static bool sign_bit( float64_t f ) { return f.v >> 63; } - }; class producer_api : public context_aware_api { @@ -922,7 +907,6 @@ public: :context_aware_api(ctx,true){} void abort() { - edump(("abort() called")); EOS_ASSERT( false, abort_called, "abort() called"); } @@ -930,7 +914,6 @@ public: void eosio_assert( bool condition, null_terminated_ptr msg ) { if( BOOST_UNLIKELY( !condition ) ) { std::string message( msg ); - edump((message)); EOS_THROW( eosio_assert_message_exception, "assertion failure with message: ${s}", ("s",message) ); } } @@ -938,14 +921,12 @@ public: void eosio_assert_message( bool condition, array_ptr msg, size_t msg_len ) { if( BOOST_UNLIKELY( !condition ) ) { std::string message( msg, msg_len ); - edump((message)); EOS_THROW( eosio_assert_message_exception, "assertion failure with message: ${s}", ("s",message) ); } } void eosio_assert_code( bool condition, uint64_t error_code ) { if( BOOST_UNLIKELY( !condition ) ) { - edump((error_code)); EOS_THROW( eosio_assert_code_exception, "assertion failure with error code: ${error_code}", ("error_code", error_code) ); } @@ -1515,18 +1496,18 @@ class compiler_builtins : public context_aware_api { // conversion long double void __extendsftf2( float128_t& ret, float f ) { - ret = f32_to_f128( softfloat_api::to_softfloat32(f) ); + ret = f32_to_f128( to_softfloat32(f) ); } void __extenddftf2( float128_t& ret, double d ) { - ret = f64_to_f128( softfloat_api::to_softfloat64(d) ); + ret = f64_to_f128( to_softfloat64(d) ); } double __trunctfdf2( uint64_t l, uint64_t h ) { float128_t f = {{ l, h }}; - return softfloat_api::from_softfloat64(f128_to_f64( f )); + return from_softfloat64(f128_to_f64( f )); } float __trunctfsf2( uint64_t l, uint64_t h ) { float128_t f = {{ l, h }}; - return softfloat_api::from_softfloat32(f128_to_f32( f )); + return from_softfloat32(f128_to_f32( f )); } int32_t __fixtfsi( uint64_t l, uint64_t h ) { float128_t f = {{ l, h }}; @@ -1553,19 +1534,19 @@ class compiler_builtins : public context_aware_api { ret = ___fixunstfti( f ); } void __fixsfti( __int128& ret, float a ) { - ret = ___fixsfti( softfloat_api::to_softfloat32(a).v ); + ret = ___fixsfti( to_softfloat32(a).v ); } void __fixdfti( __int128& ret, double a ) { - ret = ___fixdfti( softfloat_api::to_softfloat64(a).v ); + ret = ___fixdfti( to_softfloat64(a).v ); } void __fixunssfti( unsigned __int128& ret, float a ) { - ret = ___fixunssfti( softfloat_api::to_softfloat32(a).v ); + ret = ___fixunssfti( to_softfloat32(a).v ); } void __fixunsdfti( unsigned __int128& ret, double a ) { - ret = ___fixunsdfti( softfloat_api::to_softfloat64(a).v ); + ret = ___fixunsdfti( to_softfloat64(a).v ); } double __floatsidf( int32_t i ) { - return softfloat_api::from_softfloat64(i32_to_f64(i)); + return from_softfloat64(i32_to_f64(i)); } void __floatsitf( float128_t& ret, int32_t i ) { ret = i32_to_f128(i); diff --git a/libraries/fc b/libraries/fc index 9adee183df3ce4170d1f362c96d960132bd77ed9..a8613d3786cddfcc336808d2b9b7df655e6cc6d1 160000 --- a/libraries/fc +++ b/libraries/fc @@ -1 +1 @@ -Subproject commit 9adee183df3ce4170d1f362c96d960132bd77ed9 +Subproject commit a8613d3786cddfcc336808d2b9b7df655e6cc6d1 diff --git a/libraries/softfloat b/libraries/softfloat index 9942875eb704369db297eb289aa4e9912bddcfb8..203b6df7dedc5bae1b2a7b1b23562335a6344578 160000 --- a/libraries/softfloat +++ b/libraries/softfloat @@ -1 +1 @@ -Subproject commit 9942875eb704369db297eb289aa4e9912bddcfb8 +Subproject commit 203b6df7dedc5bae1b2a7b1b23562335a6344578 diff --git a/libraries/testing/CMakeLists.txt b/libraries/testing/CMakeLists.txt index 620c7fb40036c405fe9b6254f05a457bc7ac75ce..eaf9bf8750266001186f3f6606e7439692578235 100644 --- a/libraries/testing/CMakeLists.txt +++ b/libraries/testing/CMakeLists.txt @@ -7,7 +7,7 @@ add_library( eosio_testing ${HEADERS} ) -target_link_libraries( eosio_testing eosio_chain eos_utilities fc chainbase Logging IR WAST WASM Runtime ) +target_link_libraries( eosio_testing eosio_chain fc chainbase Logging IR WAST WASM Runtime ) target_include_directories( eosio_testing PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" "${CMAKE_CURRENT_BINARY_DIR}/include" "${CMAKE_CURRENT_SOURCE_DIR}/../wasm-jit/Include" diff --git a/libraries/testing/include/eosio/testing/tester.hpp b/libraries/testing/include/eosio/testing/tester.hpp index 9a4f40943303656f438272b77ec75bd5bb1a32d9..10e7d4499e2513aba8ba8bfc1ae574d2a3e6a55f 100644 --- a/libraries/testing/include/eosio/testing/tester.hpp +++ b/libraries/testing/include/eosio/testing/tester.hpp @@ -91,6 +91,7 @@ namespace eosio { namespace testing { virtual signed_block_ptr produce_block( fc::microseconds skip_time = fc::milliseconds(config::block_interval_ms), uint32_t skip_flag = 0/*skip_missed_block_penalty*/ ) = 0; virtual signed_block_ptr produce_empty_block( fc::microseconds skip_time = fc::milliseconds(config::block_interval_ms), uint32_t skip_flag = 0/*skip_missed_block_penalty*/ ) = 0; + virtual signed_block_ptr finish_block() = 0; void produce_blocks( uint32_t n = 1, bool empty = false ); void produce_blocks_until_end_of_round(); void produce_blocks_for_n_rounds(const uint32_t num_of_rounds = 1); @@ -271,6 +272,7 @@ namespace eosio { namespace testing { protected: signed_block_ptr _produce_block( fc::microseconds skip_time, bool skip_pending_trxs = false, uint32_t skip_flag = 0 ); void _start_block(fc::time_point block_time); + signed_block_ptr _finish_block(); // Fields: protected: @@ -304,6 +306,10 @@ namespace eosio { namespace testing { return _produce_block(skip_time, true, skip_flag); } + signed_block_ptr finish_block()override { + return _finish_block(); + } + bool validate() { return true; } }; @@ -351,7 +357,7 @@ namespace eosio { namespace testing { validating_node = std::make_unique(vcfg); validating_node->add_indices(); - validating_node->startup(); + validating_node->startup( []() { return false; } ); init(true); } @@ -366,14 +372,15 @@ namespace eosio { namespace testing { validating_node = std::make_unique(vcfg); validating_node->add_indices(); - validating_node->startup(); + validating_node->startup( []() { return false; } ); init(config); } signed_block_ptr produce_block( fc::microseconds skip_time = fc::milliseconds(config::block_interval_ms), uint32_t skip_flag = 0 /*skip_missed_block_penalty*/ )override { auto sb = _produce_block(skip_time, false, skip_flag | 2); - validating_node->push_block( sb ); + auto bs = validating_node->create_block_state_future( sb ); + validating_node->push_block( bs ); return sb; } @@ -383,19 +390,23 @@ namespace eosio { namespace testing { } void validate_push_block(const signed_block_ptr& sb) { - validating_node->push_block( sb ); + auto bs = validating_node->create_block_state_future( sb ); + validating_node->push_block( bs ); } signed_block_ptr produce_empty_block( fc::microseconds skip_time = fc::milliseconds(config::block_interval_ms), uint32_t skip_flag = 0 /*skip_missed_block_penalty*/ )override { control->abort_block(); auto sb = _produce_block(skip_time, true, skip_flag | 2); - validating_node->push_block( sb ); - - + auto bs = validating_node->create_block_state_future( sb ); + validating_node->push_block( bs ); return sb; } + signed_block_ptr finish_block()override { + return _finish_block(); + } + bool validate() { @@ -411,7 +422,7 @@ namespace eosio { namespace testing { validating_node.reset(); validating_node = std::make_unique(vcfg); validating_node->add_indices(); - validating_node->startup(); + validating_node->startup( []() { return false; } ); return ok; } diff --git a/libraries/testing/tester.cpp b/libraries/testing/tester.cpp index b116d1a49696285e55ba6d9c88c627650a6a9913..a2307904da38d54e80750405e5860232acfdaa57 100644 --- a/libraries/testing/tester.cpp +++ b/libraries/testing/tester.cpp @@ -124,7 +124,7 @@ namespace eosio { namespace testing { void base_tester::open( const snapshot_reader_ptr& snapshot) { control.reset( new controller(cfg) ); control->add_indices(); - control->startup(snapshot); + control->startup( []() { return false; }, snapshot); chain_transactions.clear(); control->accepted_block.connect([this]( const block_state_ptr& block_state ){ FC_ASSERT( block_state->block ); @@ -141,8 +141,9 @@ namespace eosio { namespace testing { } signed_block_ptr base_tester::push_block(signed_block_ptr b) { + auto bs = control->create_block_state_future(b); control->abort_block(); - control->push_block(b); + control->push_block(bs); auto itr = last_produced_block.find(b->producer); if (itr == last_produced_block.end() || block_header::num_from_id(b->id()) > block_header::num_from_id(itr->second)) { @@ -161,17 +162,6 @@ namespace eosio { namespace testing { _start_block( next_time ); } - auto producer = control->head_block_state()->get_scheduled_producer(next_time); - private_key_type priv_key; - // Check if signing private key exist in the list - auto private_key_itr = block_signing_private_keys.find( producer.block_signing_key ); - if( private_key_itr == block_signing_private_keys.end() ) { - // If it's not found, default to active k1 key - priv_key = get_private_key( producer.producer_name, "active" ); - } else { - priv_key = private_key_itr->second; - } - if( !skip_pending_trxs ) { auto unapplied_trxs = control->get_unapplied_transactions(); for (const auto& trx : unapplied_trxs ) { @@ -192,18 +182,10 @@ namespace eosio { namespace testing { } } - - - control->finalize_block(); - control->sign_block( [&]( digest_type d ) { - return priv_key.sign(d); - }); - - control->commit_block(); - last_produced_block[control->head_block_state()->header.producer] = control->head_block_state()->id; + auto head_block = _finish_block(); _start_block( next_time + fc::microseconds(config::block_interval_us)); - return control->head_block_state()->block; + return head_block; } void base_tester::_start_block(fc::time_point block_time) { @@ -220,6 +202,30 @@ namespace eosio { namespace testing { control->start_block( block_time, head_block_number - last_produced_block_num ); } + signed_block_ptr base_tester::_finish_block() { + FC_ASSERT( control->pending_block_state(), "must first start a block before it can be finished" ); + + auto producer = control->head_block_state()->get_scheduled_producer( control->pending_block_time() ); + private_key_type priv_key; + // Check if signing private key exist in the list + auto private_key_itr = block_signing_private_keys.find( producer.block_signing_key ); + if( private_key_itr == block_signing_private_keys.end() ) { + // If it's not found, default to active k1 key + priv_key = get_private_key( producer.producer_name, "active" ); + } else { + priv_key = private_key_itr->second; + } + + control->finalize_block(); + control->sign_block( [&]( digest_type d ) { + return priv_key.sign(d); + }); + + control->commit_block(); + last_produced_block[control->head_block_state()->header.producer] = control->head_block_state()->id; + + return control->head_block_state()->block; + } void base_tester::produce_blocks( uint32_t n, bool empty ) { if( empty ) { @@ -795,8 +801,9 @@ namespace eosio { namespace testing { for( int i = 1; i <= a.control->head_block_num(); ++i ) { auto block = a.control->fetch_block_by_number(i); if( block ) { //&& !b.control->is_known_block(block->id()) ) { + auto bs = b.control->create_block_state_future( block ); b.control->abort_block(); - b.control->push_block(block); //, eosio::chain::validation_steps::created_block); + b.control->push_block(bs); //, eosio::chain::validation_steps::created_block); } } }; diff --git a/libraries/utilities/CMakeLists.txt b/libraries/utilities/CMakeLists.txt deleted file mode 100644 index 4aed508d14f8e25da81556ee512ef26b8b491f48..0000000000000000000000000000000000000000 --- a/libraries/utilities/CMakeLists.txt +++ /dev/null @@ -1,32 +0,0 @@ -#list( APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/libraries/fc/GitVersionGen" ) -#include( GetGitRevisionDescription ) -#get_git_head_revision(GIT_REFSPEC EOS_GIT_REVISION_SHA) -#get_git_unix_timestamp(EOS_GIT_REVISION_UNIX_TIMESTAMP) -#git_describe(EOS_GIT_REVISION_DESCRIPTION --tags) -if(NOT EOS_GIT_REVISION_DESCRIPTION) - set(EOS_GIT_REVISION_DESCRIPTION "unknown") -endif(NOT EOS_GIT_REVISION_DESCRIPTION) - -file(GLOB HEADERS "include/eosio/utilities/*.hpp") - -set(sources - key_conversion.cpp - string_escape.cpp - tempdir.cpp - words.cpp - ${HEADERS}) - -#configure_file("${CMAKE_CURRENT_SOURCE_DIR}/git_revision.cpp.in" "${CMAKE_CURRENT_BINARY_DIR}/git_revision.cpp" @ONLY) -#list(APPEND sources "${CMAKE_CURRENT_BINARY_DIR}/git_revision.cpp") - -add_library( eos_utilities - ${sources} - ${HEADERS} ) -target_link_libraries( eos_utilities fc WAST WASM ) -target_include_directories( eos_utilities - PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" - "${CMAKE_CURRENT_SOURCE_DIR}/../wasm-jit/Include" ) -if (USE_PCH) - set_target_properties(eos_utilities PROPERTIES COTIRE_ADD_UNITY_BUILD FALSE) - cotire(eos_utilities) -endif(USE_PCH) diff --git a/libraries/utilities/git_revision.cpp.in b/libraries/utilities/git_revision.cpp.in deleted file mode 100644 index 9c52da41307ea862a45b42a1094ed2561a649d4a..0000000000000000000000000000000000000000 --- a/libraries/utilities/git_revision.cpp.in +++ /dev/null @@ -1,14 +0,0 @@ -#include -#include - -#define EOS_GIT_REVISION_SHA "@EOS_GIT_REVISION_SHA@" -#define EOS_GIT_REVISION_UNIX_TIMESTAMP @EOS_GIT_REVISION_UNIX_TIMESTAMP@ -#define EOS_GIT_REVISION_DESCRIPTION "@EOS_GIT_REVISION_DESCRIPTION@" - -namespace eosio { namespace utilities { - -const char* const git_revision_sha = EOS_GIT_REVISION_SHA; -const uint32_t git_revision_unix_timestamp = EOS_GIT_REVISION_UNIX_TIMESTAMP; -const char* const git_revision_description = EOS_GIT_REVISION_DESCRIPTION; - -} } // end namespace eosio::utilities diff --git a/libraries/utilities/include/eosio/utilities/common.hpp b/libraries/utilities/include/eosio/utilities/common.hpp deleted file mode 100644 index 793a3d58e7a768f2de8f2c84903faa000304baa4..0000000000000000000000000000000000000000 --- a/libraries/utilities/include/eosio/utilities/common.hpp +++ /dev/null @@ -1,22 +0,0 @@ -/** - * @file - * @copyright defined in eos/LICENSE.txt - * - */ -#pragma once - -#ifndef COMMON_HPP -#define COMMON_HPP - -namespace eosio { namespace utilities { namespace common { - template - std::string itoh(I n, size_t hlen = sizeof(I)<<1) { - static const char* digits = "0123456789abcdef"; - std::string r(hlen, '0'); - for(size_t i = 0, j = (hlen - 1) * 4 ; i < hlen; ++i, j -= 4) - r[i] = digits[(n>>j) & 0x0f]; - return r; - } -}}} - -#endif // COMMON_HPP diff --git a/libraries/utilities/include/eosio/utilities/git_revision.hpp b/libraries/utilities/include/eosio/utilities/git_revision.hpp deleted file mode 100644 index 85697d645ebf058311a54e5e7c8d7f8008e41c54..0000000000000000000000000000000000000000 --- a/libraries/utilities/include/eosio/utilities/git_revision.hpp +++ /dev/null @@ -1,14 +0,0 @@ -/** - * @file - * @copyright defined in eos/LICENSE.txt - */ -#pragma once -#include - -namespace eosio { namespace utilities { - -extern const char* const git_revision_sha; -extern const uint32_t git_revision_unix_timestamp; -extern const char* const git_revision_description; - -} } // end namespace eosio::utilities diff --git a/libraries/utilities/include/eosio/utilities/key_conversion.hpp b/libraries/utilities/include/eosio/utilities/key_conversion.hpp deleted file mode 100644 index 0d6daaf903a884001d63552a3b5f0270baec735c..0000000000000000000000000000000000000000 --- a/libraries/utilities/include/eosio/utilities/key_conversion.hpp +++ /dev/null @@ -1,17 +0,0 @@ -/** - * @file - * @copyright defined in eos/LICENSE.txt - */ -#pragma once - -#include -#include -#include - -namespace eosio { namespace utilities { - -std::string key_to_wif(const fc::sha256& private_secret ); -std::string key_to_wif(const fc::ecc::private_key& key); -fc::optional wif_to_key( const std::string& wif_key ); - -} } // end namespace eosio::utilities diff --git a/libraries/utilities/include/eosio/utilities/padding_ostream.hpp b/libraries/utilities/include/eosio/utilities/padding_ostream.hpp deleted file mode 100644 index fbf7a34396af842a360e819b25924d625c93f597..0000000000000000000000000000000000000000 --- a/libraries/utilities/include/eosio/utilities/padding_ostream.hpp +++ /dev/null @@ -1,39 +0,0 @@ -/** - * @file - * @copyright defined in eos/LICENSE.txt - */ -#pragma once - -namespace eosio { namespace utilities { - -template -class padding_ostream : public fc::buffered_ostream { -public: - padding_ostream( fc::ostream_ptr o, size_t bufsize = 4096 ) : buffered_ostream(o, bufsize) {} - virtual ~padding_ostream() {} - - virtual size_t writesome( const char* buffer, size_t len ) { - auto out = buffered_ostream::writesome(buffer, len); - bytes_out += out; - bytes_out %= BlockSize; - return out; - } - virtual size_t writesome( const std::shared_ptr& buf, size_t len, size_t offset ) { - auto out = buffered_ostream::writesome(buf, len, offset); - bytes_out += out; - bytes_out %= BlockSize; - return out; - } - virtual void flush() { - static const char pad = PaddingChar; - while( bytes_out % BlockSize ) - writesome(&pad, 1); - buffered_ostream::flush(); - } - -private: - size_t bytes_out = 0; -}; - -} } //eosio::utilities - diff --git a/libraries/utilities/include/eosio/utilities/rand.hpp b/libraries/utilities/include/eosio/utilities/rand.hpp deleted file mode 100644 index 556f706d1b356d688655f6258e9e6968d6a336a9..0000000000000000000000000000000000000000 --- a/libraries/utilities/include/eosio/utilities/rand.hpp +++ /dev/null @@ -1,44 +0,0 @@ -/** - * @file - * @copyright defined in eos/LICENSE.txt - */ -#ifndef RAND_HPP -#define RAND_HPP 1 - -#include - -namespace eosio { namespace utilities { namespace rand { - -/// High performance random generator -/// http://xorshift.di.unimi.it/ - -class random { -private: - - uint64_t seed; - -public: - - random(uint64_t seed) { - this->seed = seed; - } - - uint64_t next() { - uint64_t z = (seed += UINT64_C(0x9E3779B97F4A7C15)); - z = (z ^ (z >> 30)) * UINT64_C(0xBF58476D1CE4E5B9); - z = (z ^ (z >> 27)) * UINT64_C(0x94D049BB133111EB); - return z ^ (z >> 31); - } - - template - void shuffle(Range&& range) { - int idx_count = range.size(); - for (auto idx = range.rbegin(); idx != range.rend() - 1; ++idx , --idx_count) { - std::swap(range.at(next() % idx_count), *idx); - } - } -}; - -} } } //eosio::utilities::rand - -#endif // RAND_HPP diff --git a/libraries/utilities/include/eosio/utilities/string_escape.hpp b/libraries/utilities/include/eosio/utilities/string_escape.hpp deleted file mode 100644 index 03870b73e2db3882bad07fcc1dbb8df65f45bbe1..0000000000000000000000000000000000000000 --- a/libraries/utilities/include/eosio/utilities/string_escape.hpp +++ /dev/null @@ -1,13 +0,0 @@ -/** - * @file - * @copyright defined in eos/LICENSE.txt - */ -#pragma once - -#include - -namespace eosio { namespace utilities { - - std::string escape_string_for_c_source_code(const std::string& input); - -} } // end namespace eosio::utilities diff --git a/libraries/utilities/include/eosio/utilities/tempdir.hpp b/libraries/utilities/include/eosio/utilities/tempdir.hpp deleted file mode 100644 index 0151a7d88a78dd1171789293743809fe843625b9..0000000000000000000000000000000000000000 --- a/libraries/utilities/include/eosio/utilities/tempdir.hpp +++ /dev/null @@ -1,15 +0,0 @@ -/** - * @file - * @copyright defined in eos/LICENSE.txt - */ -#pragma once - -#include - -#include - -namespace eosio { namespace utilities { - -fc::path temp_directory_path(); - -} } // eosio::utilities diff --git a/libraries/utilities/include/eosio/utilities/words.hpp b/libraries/utilities/include/eosio/utilities/words.hpp deleted file mode 100644 index cc1ead427a7b41b9053b5c56d50c21ba94ad5e1f..0000000000000000000000000000000000000000 --- a/libraries/utilities/include/eosio/utilities/words.hpp +++ /dev/null @@ -1,13 +0,0 @@ -/** - * @file - * @copyright defined in eos/LICENSE.txt - */ -#pragma once - -namespace eosio { namespace words { - -typedef const char* const_char_ptr; -extern const const_char_ptr word_list[]; -extern const uint32_t word_list_size; - -} } diff --git a/libraries/utilities/key_conversion.cpp b/libraries/utilities/key_conversion.cpp deleted file mode 100644 index 693514f6c99769e40b13fa2406319ff034ad82cc..0000000000000000000000000000000000000000 --- a/libraries/utilities/key_conversion.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/** - * @file - * @copyright defined in eos/LICENSE.txt - */ -#include -#include -#include - -namespace eosio { namespace utilities { - -std::string key_to_wif(const fc::sha256& secret ) -{ - const size_t size_of_data_to_hash = sizeof(secret) + 1; - const size_t size_of_hash_bytes = 4; - char data[size_of_data_to_hash + size_of_hash_bytes]; - data[0] = (char)0x80; - memcpy(&data[1], (char*)&secret, sizeof(secret)); - fc::sha256 digest = fc::sha256::hash(data, size_of_data_to_hash); - digest = fc::sha256::hash(digest); - memcpy(data + size_of_data_to_hash, (char*)&digest, size_of_hash_bytes); - return fc::to_base58(data, sizeof(data)); -} -std::string key_to_wif(const fc::ecc::private_key& key) -{ - return key_to_wif( key.get_secret() ); -} - -fc::optional wif_to_key( const std::string& wif_key ) -{ - std::vector wif_bytes; - try - { - wif_bytes = fc::from_base58(wif_key); - } - catch (const fc::parse_error_exception&) - { - return fc::optional(); - } - if (wif_bytes.size() < 5) - return fc::optional(); - std::vector key_bytes(wif_bytes.begin() + 1, wif_bytes.end() - 4); - fc::ecc::private_key key = fc::variant(key_bytes).as(); - fc::sha256 check = fc::sha256::hash(wif_bytes.data(), wif_bytes.size() - 4); - fc::sha256 check2 = fc::sha256::hash(check); - - if( memcmp( (char*)&check, wif_bytes.data() + wif_bytes.size() - 4, 4 ) == 0 || - memcmp( (char*)&check2, wif_bytes.data() + wif_bytes.size() - 4, 4 ) == 0 ) - return key; - - return fc::optional(); -} - -} } // end namespace eosio::utilities diff --git a/libraries/utilities/string_escape.cpp b/libraries/utilities/string_escape.cpp deleted file mode 100644 index 05421b327c3bda5ed976eaafdb2349e69dfd23ba..0000000000000000000000000000000000000000 --- a/libraries/utilities/string_escape.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/** - * @file - * @copyright defined in eos/LICENSE.txt - */ - -#include -#include - -namespace eosio { namespace utilities { - - std::string escape_string_for_c_source_code(const std::string& input) - { - std::ostringstream escaped_string; - escaped_string << "\""; - for (unsigned i = 0; i < input.size(); ++i) - { - switch (input[i]) - { - case '\a': - escaped_string << "\\a"; - break; - case '\b': - escaped_string << "\\b"; - break; - case '\t': - escaped_string << "\\t"; - break; - case '\n': - escaped_string << "\\n"; - break; - case '\v': - escaped_string << "\\v"; - break; - case '\f': - escaped_string << "\\f"; - break; - case '\r': - escaped_string << "\\r"; - break; - case '\\': - escaped_string << "\\\\"; - break; - case '\"': - escaped_string << "\\\""; - break; - default: - escaped_string << input[i]; - } - } - escaped_string << "\""; - return escaped_string.str(); - } - -} } // end namespace eosio::utilities - diff --git a/libraries/utilities/tempdir.cpp b/libraries/utilities/tempdir.cpp deleted file mode 100644 index 5aae9cbbede7478e11204c35b27471bf72cd9466..0000000000000000000000000000000000000000 --- a/libraries/utilities/tempdir.cpp +++ /dev/null @@ -1,20 +0,0 @@ -/** - * @file - * @copyright defined in eos/LICENSE.txt - */ - -#include - -#include - -namespace eosio { namespace utilities { - -fc::path temp_directory_path() -{ - const char* eos_tempdir = getenv("EOS_TEMPDIR"); - if( eos_tempdir != nullptr ) - return fc::path( eos_tempdir ); - return fc::temp_directory_path() / "eos-tmp"; -} - -} } // eosio::utilities diff --git a/libraries/utilities/words.cpp b/libraries/utilities/words.cpp deleted file mode 100644 index 0da88e78af50e2def477e80e9762b8d78325b837..0000000000000000000000000000000000000000 --- a/libraries/utilities/words.cpp +++ /dev/null @@ -1,49764 +0,0 @@ -/** - * @file - * @copyright defined in eos/LICENSE.txt - */ -#include -#include - -namespace eosio { namespace words { - -const const_char_ptr word_list[] = { -"a", -"aa", -"aal", -"aalii", -"aam", -"aba", -"abac", -"abaca", -"abacate", -"abacay", -"abacist", -"aback", -"abactor", -"abacus", -"abaff", -"abaft", -"abaiser", -"abalone", -"abandon", -"abas", -"abase", -"abased", -"abaser", -"abash", -"abashed", -"abasia", -"abasic", -"abask", -"abate", -"abater", -"abatis", -"abaton", -"abator", -"abature", -"abave", -"abaxial", -"abaxile", -"abaze", -"abb", -"abbacy", -"abbas", -"abbasi", -"abbassi", -"abbess", -"abbey", -"abbot", -"abbotcy", -"abdal", -"abdat", -"abdest", -"abdomen", -"abduce", -"abduct", -"abeam", -"abear", -"abed", -"abeigh", -"abele", -"abelite", -"abet", -"abettal", -"abettor", -"abey", -"abeyant", -"abfarad", -"abhenry", -"abhor", -"abidal", -"abide", -"abider", -"abidi", -"abiding", -"abietic", -"abietin", -"abigail", -"abigeat", -"abigeus", -"abilao", -"ability", -"abilla", -"abilo", -"abiosis", -"abiotic", -"abir", -"abiston", -"abiuret", -"abject", -"abjoint", -"abjudge", -"abjure", -"abjurer", -"abkar", -"abkari", -"ablach", -"ablare", -"ablate", -"ablator", -"ablaut", -"ablaze", -"able", -"ableeze", -"abler", -"ablest", -"ablins", -"abloom", -"ablow", -"ablude", -"abluent", -"ablush", -"ably", -"abmho", -"abnet", -"aboard", -"abode", -"abody", -"abohm", -"aboil", -"abolish", -"abolla", -"aboma", -"abomine", -"aboon", -"aborad", -"aboral", -"abord", -"abort", -"aborted", -"abortin", -"abortus", -"abound", -"about", -"abouts", -"above", -"abox", -"abrade", -"abrader", -"abraid", -"abrasax", -"abrase", -"abrash", -"abraum", -"abraxas", -"abreact", -"abreast", -"abret", -"abrico", -"abridge", -"abrim", -"abrin", -"abroach", -"abroad", -"abrook", -"abrupt", -"abscess", -"abscind", -"abscise", -"absciss", -"abscond", -"absence", -"absent", -"absit", -"absmho", -"absohm", -"absolve", -"absorb", -"absorpt", -"abstain", -"absume", -"absurd", -"absvolt", -"abthain", -"abu", -"abucco", -"abulia", -"abulic", -"abuna", -"abura", -"aburban", -"aburst", -"aburton", -"abuse", -"abusee", -"abuser", -"abusion", -"abusive", -"abut", -"abuttal", -"abutter", -"abuzz", -"abvolt", -"abwab", -"aby", -"abysm", -"abysmal", -"abyss", -"abyssal", -"acaciin", -"acacin", -"academe", -"academy", -"acajou", -"acaleph", -"acana", -"acanth", -"acantha", -"acapnia", -"acapu", -"acara", -"acardia", -"acari", -"acarian", -"acarid", -"acarine", -"acaroid", -"acarol", -"acate", -"acatery", -"acaudal", -"acca", -"accede", -"acceder", -"accend", -"accent", -"accept", -"accerse", -"access", -"accidia", -"accidie", -"accinge", -"accite", -"acclaim", -"accloy", -"accoast", -"accoil", -"accolle", -"accompt", -"accord", -"accost", -"account", -"accoy", -"accrete", -"accrual", -"accrue", -"accruer", -"accurse", -"accusal", -"accuse", -"accused", -"accuser", -"ace", -"acedia", -"acedy", -"acephal", -"acerate", -"acerb", -"acerbic", -"acerdol", -"acerin", -"acerose", -"acerous", -"acerra", -"aceship", -"acetal", -"acetate", -"acetic", -"acetify", -"acetin", -"acetize", -"acetoin", -"acetol", -"acetone", -"acetose", -"acetous", -"acetum", -"acetyl", -"ach", -"achage", -"achar", -"achate", -"ache", -"achene", -"acher", -"achete", -"achieve", -"achigan", -"achill", -"achime", -"aching", -"achira", -"acholia", -"acholic", -"achor", -"achree", -"achroma", -"achtel", -"achy", -"achylia", -"achymia", -"acicula", -"acid", -"acider", -"acidic", -"acidify", -"acidite", -"acidity", -"acidize", -"acidly", -"acidoid", -"acidyl", -"acier", -"aciform", -"acinar", -"acinary", -"acinic", -"acinose", -"acinous", -"acinus", -"aciurgy", -"acker", -"ackey", -"ackman", -"acknow", -"acle", -"aclinal", -"aclinic", -"acloud", -"aclys", -"acmatic", -"acme", -"acmic", -"acmite", -"acne", -"acnemia", -"acnodal", -"acnode", -"acock", -"acocotl", -"acoin", -"acoine", -"acold", -"acology", -"acolous", -"acolyte", -"acoma", -"acomia", -"acomous", -"acone", -"aconic", -"aconin", -"aconine", -"aconite", -"acopic", -"acopon", -"acor", -"acorea", -"acoria", -"acorn", -"acorned", -"acosmic", -"acouasm", -"acouchi", -"acouchy", -"acoupa", -"acquest", -"acquire", -"acquist", -"acquit", -"acracy", -"acraein", -"acrasia", -"acratia", -"acrawl", -"acraze", -"acre", -"acreage", -"acreak", -"acream", -"acred", -"acreman", -"acrid", -"acridan", -"acridic", -"acridly", -"acridyl", -"acrinyl", -"acrisia", -"acritan", -"acrite", -"acritol", -"acroama", -"acrobat", -"acrogen", -"acron", -"acronyc", -"acronym", -"acronyx", -"acrook", -"acrose", -"across", -"acrotic", -"acryl", -"acrylic", -"acrylyl", -"act", -"acta", -"actable", -"actify", -"actin", -"actinal", -"actine", -"acting", -"actinic", -"actinon", -"action", -"active", -"activin", -"actless", -"acton", -"actor", -"actress", -"actu", -"actual", -"actuary", -"acture", -"acuate", -"acuity", -"aculea", -"aculeus", -"acumen", -"acushla", -"acutate", -"acute", -"acutely", -"acutish", -"acyclic", -"acyesis", -"acyetic", -"acyl", -"acylate", -"acyloin", -"acyloxy", -"acystia", -"ad", -"adactyl", -"adad", -"adage", -"adagial", -"adagio", -"adamant", -"adamas", -"adamine", -"adamite", -"adance", -"adangle", -"adapid", -"adapt", -"adapter", -"adaptor", -"adarme", -"adat", -"adati", -"adatom", -"adaunt", -"adaw", -"adawe", -"adawlut", -"adawn", -"adaxial", -"aday", -"adays", -"adazzle", -"adcraft", -"add", -"adda", -"addable", -"addax", -"added", -"addedly", -"addend", -"addenda", -"adder", -"addible", -"addict", -"addle", -"addlins", -"address", -"addrest", -"adduce", -"adducer", -"adduct", -"ade", -"adead", -"adeem", -"adeep", -"adeling", -"adelite", -"adenase", -"adenia", -"adenine", -"adenoid", -"adenoma", -"adenose", -"adenyl", -"adept", -"adermia", -"adermin", -"adet", -"adevism", -"adfix", -"adhaka", -"adharma", -"adhere", -"adherer", -"adhibit", -"adiate", -"adicity", -"adieu", -"adieux", -"adinole", -"adion", -"adipate", -"adipic", -"adipoid", -"adipoma", -"adipose", -"adipous", -"adipsia", -"adipsic", -"adipsy", -"adipyl", -"adit", -"adital", -"aditus", -"adjag", -"adject", -"adjiger", -"adjoin", -"adjoint", -"adjourn", -"adjudge", -"adjunct", -"adjure", -"adjurer", -"adjust", -"adlay", -"adless", -"adlet", -"adman", -"admi", -"admiral", -"admire", -"admired", -"admirer", -"admit", -"admix", -"adnate", -"adnex", -"adnexal", -"adnexed", -"adnoun", -"ado", -"adobe", -"adonin", -"adonite", -"adonize", -"adopt", -"adopted", -"adoptee", -"adopter", -"adoral", -"adorant", -"adore", -"adorer", -"adorn", -"adorner", -"adossed", -"adoulie", -"adown", -"adoxy", -"adoze", -"adpao", -"adpress", -"adread", -"adream", -"adreamt", -"adrenal", -"adrenin", -"adrift", -"adrip", -"adroit", -"adroop", -"adrop", -"adrowse", -"adrue", -"adry", -"adsbud", -"adsmith", -"adsorb", -"adtevac", -"adular", -"adulate", -"adult", -"adulter", -"adunc", -"adusk", -"adust", -"advance", -"advene", -"adverb", -"adverse", -"advert", -"advice", -"advisal", -"advise", -"advised", -"advisee", -"adviser", -"advisor", -"advowee", -"ady", -"adynamy", -"adyta", -"adyton", -"adytum", -"adz", -"adze", -"adzer", -"adzooks", -"ae", -"aecial", -"aecium", -"aedile", -"aedilic", -"aefald", -"aefaldy", -"aefauld", -"aegis", -"aenach", -"aenean", -"aeneous", -"aeolid", -"aeolina", -"aeoline", -"aeon", -"aeonial", -"aeonian", -"aeonist", -"aer", -"aerage", -"aerate", -"aerator", -"aerial", -"aeric", -"aerical", -"aerie", -"aeried", -"aerify", -"aero", -"aerobe", -"aerobic", -"aerobus", -"aerogel", -"aerogen", -"aerogun", -"aeronat", -"aeronef", -"aerose", -"aerosol", -"aerugo", -"aery", -"aes", -"aevia", -"aface", -"afaint", -"afar", -"afara", -"afear", -"afeard", -"afeared", -"afernan", -"afetal", -"affa", -"affable", -"affably", -"affair", -"affaite", -"affect", -"affeer", -"affeir", -"affiant", -"affinal", -"affine", -"affined", -"affirm", -"affix", -"affixal", -"affixer", -"afflict", -"afflux", -"afforce", -"afford", -"affray", -"affront", -"affuse", -"affy", -"afghani", -"afield", -"afire", -"aflame", -"aflare", -"aflat", -"aflaunt", -"aflight", -"afloat", -"aflow", -"aflower", -"aflush", -"afoam", -"afoot", -"afore", -"afoul", -"afraid", -"afreet", -"afresh", -"afret", -"afront", -"afrown", -"aft", -"aftaba", -"after", -"aftergo", -"aftmost", -"aftosa", -"aftward", -"aga", -"again", -"against", -"agal", -"agalaxy", -"agalite", -"agallop", -"agalma", -"agama", -"agamete", -"agami", -"agamian", -"agamic", -"agamid", -"agamoid", -"agamont", -"agamous", -"agamy", -"agape", -"agapeti", -"agar", -"agaric", -"agarita", -"agarwal", -"agasp", -"agate", -"agathin", -"agatine", -"agatize", -"agatoid", -"agaty", -"agavose", -"agaze", -"agazed", -"age", -"aged", -"agedly", -"agee", -"ageless", -"agelong", -"agen", -"agency", -"agenda", -"agendum", -"agent", -"agentry", -"ager", -"ageusia", -"ageusic", -"agger", -"aggrade", -"aggrate", -"aggress", -"aggroup", -"aggry", -"aggur", -"agha", -"aghanee", -"aghast", -"agile", -"agilely", -"agility", -"aging", -"agio", -"agist", -"agistor", -"agitant", -"agitate", -"agla", -"aglance", -"aglare", -"agleaf", -"agleam", -"aglet", -"agley", -"aglint", -"aglow", -"aglucon", -"agnail", -"agname", -"agnamed", -"agnate", -"agnatic", -"agnel", -"agnize", -"agnomen", -"agnosia", -"agnosis", -"agnosy", -"agnus", -"ago", -"agog", -"agoge", -"agogic", -"agogics", -"agoho", -"agoing", -"agon", -"agonal", -"agone", -"agonic", -"agonied", -"agonist", -"agonium", -"agonize", -"agony", -"agora", -"agouara", -"agouta", -"agouti", -"agpaite", -"agrah", -"agral", -"agre", -"agree", -"agreed", -"agreer", -"agrege", -"agria", -"agrin", -"agrise", -"agrito", -"agroan", -"agrom", -"agroof", -"agrope", -"aground", -"agrufe", -"agruif", -"agsam", -"agua", -"ague", -"aguey", -"aguish", -"agunah", -"agush", -"agust", -"agy", -"agynary", -"agynous", -"agyrate", -"agyria", -"ah", -"aha", -"ahaaina", -"ahaunch", -"ahead", -"aheap", -"ahem", -"ahey", -"ahimsa", -"ahind", -"ahint", -"ahmadi", -"aho", -"ahong", -"ahorse", -"ahoy", -"ahsan", -"ahu", -"ahuatle", -"ahull", -"ahum", -"ahungry", -"ahunt", -"ahura", -"ahush", -"ahwal", -"ahypnia", -"ai", -"aid", -"aidable", -"aidance", -"aidant", -"aide", -"aider", -"aidful", -"aidless", -"aiel", -"aiglet", -"ail", -"ailanto", -"aile", -"aileron", -"ailette", -"ailing", -"aillt", -"ailment", -"ailsyte", -"ailuro", -"ailweed", -"aim", -"aimara", -"aimer", -"aimful", -"aiming", -"aimless", -"ainaleh", -"ainhum", -"ainoi", -"ainsell", -"aint", -"aion", -"aionial", -"air", -"airable", -"airampo", -"airan", -"aircrew", -"airdock", -"airdrop", -"aire", -"airer", -"airfoil", -"airhead", -"airily", -"airing", -"airish", -"airless", -"airlift", -"airlike", -"airmail", -"airman", -"airmark", -"airpark", -"airport", -"airship", -"airsick", -"airt", -"airward", -"airway", -"airy", -"aisle", -"aisled", -"aisling", -"ait", -"aitch", -"aitesis", -"aition", -"aiwan", -"aizle", -"ajaja", -"ajangle", -"ajar", -"ajari", -"ajava", -"ajhar", -"ajivika", -"ajog", -"ajoint", -"ajowan", -"ak", -"aka", -"akala", -"akaroa", -"akasa", -"akazga", -"akcheh", -"ake", -"akeake", -"akebi", -"akee", -"akeki", -"akeley", -"akepiro", -"akerite", -"akey", -"akhoond", -"akhrot", -"akhyana", -"akia", -"akimbo", -"akin", -"akindle", -"akinete", -"akmudar", -"aknee", -"ako", -"akoasm", -"akoasma", -"akonge", -"akov", -"akpek", -"akra", -"aku", -"akule", -"akund", -"al", -"ala", -"alacha", -"alack", -"alada", -"alaihi", -"alaite", -"alala", -"alalite", -"alalus", -"alameda", -"alamo", -"alamoth", -"alan", -"aland", -"alangin", -"alani", -"alanine", -"alannah", -"alantic", -"alantin", -"alantol", -"alanyl", -"alar", -"alares", -"alarm", -"alarmed", -"alarum", -"alary", -"alas", -"alate", -"alated", -"alatern", -"alation", -"alb", -"alba", -"alban", -"albarco", -"albata", -"albe", -"albedo", -"albee", -"albeit", -"albetad", -"albify", -"albinal", -"albinic", -"albino", -"albite", -"albitic", -"albugo", -"album", -"albumen", -"albumin", -"alburn", -"albus", -"alcaide", -"alcalde", -"alcanna", -"alcazar", -"alchemy", -"alchera", -"alchimy", -"alchymy", -"alcine", -"alclad", -"alco", -"alcoate", -"alcogel", -"alcohol", -"alcosol", -"alcove", -"alcyon", -"aldane", -"aldazin", -"aldehol", -"alder", -"aldern", -"aldim", -"aldime", -"aldine", -"aldol", -"aldose", -"ale", -"aleak", -"alec", -"alecize", -"alecost", -"alecup", -"alee", -"alef", -"aleft", -"alegar", -"alehoof", -"alem", -"alemana", -"alembic", -"alemite", -"alemmal", -"alen", -"aleph", -"alephs", -"alepole", -"alepot", -"alerce", -"alerse", -"alert", -"alertly", -"alesan", -"aletap", -"alette", -"alevin", -"alewife", -"alexia", -"alexic", -"alexin", -"aleyard", -"alf", -"alfa", -"alfaje", -"alfalfa", -"alfaqui", -"alfet", -"alfiona", -"alfonso", -"alforja", -"alga", -"algae", -"algal", -"algalia", -"algate", -"algebra", -"algedo", -"algesia", -"algesic", -"algesis", -"algetic", -"algic", -"algid", -"algific", -"algin", -"algine", -"alginic", -"algist", -"algoid", -"algor", -"algosis", -"algous", -"algum", -"alhenna", -"alias", -"alibi", -"alible", -"alichel", -"alidade", -"alien", -"aliency", -"alienee", -"aliener", -"alienor", -"alif", -"aliform", -"alight", -"align", -"aligner", -"aliipoe", -"alike", -"alima", -"aliment", -"alimony", -"alin", -"aliofar", -"alipata", -"aliped", -"aliptes", -"aliptic", -"aliquot", -"alish", -"alisier", -"alismad", -"alismal", -"aliso", -"alison", -"alisp", -"alist", -"alit", -"alite", -"aliunde", -"alive", -"aliyah", -"alizari", -"aljoba", -"alk", -"alkali", -"alkalic", -"alkamin", -"alkane", -"alkanet", -"alkene", -"alkenna", -"alkenyl", -"alkide", -"alkine", -"alkool", -"alkoxy", -"alkoxyl", -"alky", -"alkyd", -"alkyl", -"alkylic", -"alkyne", -"all", -"allan", -"allay", -"allayer", -"allbone", -"allege", -"alleger", -"allegro", -"allele", -"allelic", -"allene", -"aller", -"allergy", -"alley", -"alleyed", -"allgood", -"allheal", -"allice", -"allied", -"allies", -"allness", -"allonym", -"alloquy", -"allose", -"allot", -"allotee", -"allover", -"allow", -"allower", -"alloxan", -"alloy", -"allseed", -"alltud", -"allude", -"allure", -"allurer", -"alluvia", -"allwork", -"ally", -"allyl", -"allylic", -"alma", -"almadia", -"almadie", -"almagra", -"almanac", -"alme", -"almemar", -"almique", -"almirah", -"almoign", -"almon", -"almond", -"almondy", -"almoner", -"almonry", -"almost", -"almous", -"alms", -"almsful", -"almsman", -"almuce", -"almud", -"almude", -"almug", -"almuten", -"aln", -"alnage", -"alnager", -"alnein", -"alnico", -"alnoite", -"alnuin", -"alo", -"alochia", -"alod", -"alodial", -"alodian", -"alodium", -"alody", -"aloe", -"aloed", -"aloesol", -"aloetic", -"aloft", -"alogia", -"alogism", -"alogy", -"aloid", -"aloin", -"aloma", -"alone", -"along", -"alongst", -"aloof", -"aloofly", -"aloose", -"alop", -"alopeke", -"alose", -"aloud", -"alow", -"alowe", -"alp", -"alpaca", -"alpeen", -"alpha", -"alphol", -"alphorn", -"alphos", -"alphyl", -"alpieu", -"alpine", -"alpist", -"alquier", -"alraun", -"already", -"alright", -"alroot", -"alruna", -"also", -"alsoon", -"alt", -"altaite", -"altar", -"altared", -"alter", -"alterer", -"altern", -"alterne", -"althea", -"althein", -"altho", -"althorn", -"altilik", -"altin", -"alto", -"altoun", -"altrose", -"altun", -"aludel", -"alula", -"alular", -"alulet", -"alum", -"alumic", -"alumina", -"alumine", -"alumish", -"alumite", -"alumium", -"alumna", -"alumnae", -"alumnal", -"alumni", -"alumnus", -"alunite", -"alupag", -"alure", -"aluta", -"alvar", -"alveary", -"alveloz", -"alveola", -"alveole", -"alveoli", -"alveus", -"alvine", -"alvite", -"alvus", -"alway", -"always", -"aly", -"alypin", -"alysson", -"am", -"ama", -"amaas", -"amadou", -"amaga", -"amah", -"amain", -"amakebe", -"amala", -"amalaka", -"amalgam", -"amaltas", -"amamau", -"amandin", -"amang", -"amani", -"amania", -"amanori", -"amanous", -"amapa", -"amar", -"amarin", -"amarine", -"amarity", -"amaroid", -"amass", -"amasser", -"amastia", -"amasty", -"amateur", -"amative", -"amatol", -"amatory", -"amaze", -"amazed", -"amazia", -"amazing", -"amba", -"ambage", -"ambalam", -"amban", -"ambar", -"ambaree", -"ambary", -"ambash", -"ambassy", -"ambatch", -"ambay", -"ambeer", -"amber", -"ambery", -"ambiens", -"ambient", -"ambier", -"ambit", -"ambital", -"ambitty", -"ambitus", -"amble", -"ambler", -"ambling", -"ambo", -"ambon", -"ambos", -"ambrain", -"ambrein", -"ambrite", -"ambroid", -"ambrose", -"ambry", -"ambsace", -"ambury", -"ambush", -"amchoor", -"ame", -"ameed", -"ameen", -"amelia", -"amellus", -"amelu", -"amelus", -"amen", -"amend", -"amende", -"amender", -"amends", -"amene", -"amenia", -"amenity", -"ament", -"amental", -"amentia", -"amentum", -"amerce", -"amercer", -"amerism", -"amesite", -"ametria", -"amgarn", -"amhar", -"amhran", -"ami", -"amiable", -"amiably", -"amianth", -"amic", -"amical", -"amice", -"amiced", -"amicron", -"amid", -"amidase", -"amidate", -"amide", -"amidic", -"amidid", -"amidide", -"amidin", -"amidine", -"amido", -"amidol", -"amidon", -"amidoxy", -"amidst", -"amil", -"amimia", -"amimide", -"amin", -"aminate", -"amine", -"amini", -"aminic", -"aminity", -"aminize", -"amino", -"aminoid", -"amir", -"amiray", -"amiss", -"amity", -"amixia", -"amla", -"amli", -"amlikar", -"amlong", -"amma", -"amman", -"ammelin", -"ammer", -"ammeter", -"ammine", -"ammo", -"ammonal", -"ammonia", -"ammonic", -"ammono", -"ammu", -"amnesia", -"amnesic", -"amnesty", -"amnia", -"amniac", -"amnic", -"amnion", -"amniote", -"amober", -"amobyr", -"amoeba", -"amoebae", -"amoeban", -"amoebic", -"amoebid", -"amok", -"amoke", -"amole", -"amomal", -"amomum", -"among", -"amongst", -"amor", -"amorado", -"amoraic", -"amoraim", -"amoral", -"amoret", -"amorism", -"amorist", -"amoroso", -"amorous", -"amorphy", -"amort", -"amotion", -"amotus", -"amount", -"amour", -"amove", -"ampalea", -"amper", -"ampere", -"ampery", -"amphid", -"amphide", -"amphora", -"amphore", -"ample", -"amplify", -"amply", -"ampoule", -"ampul", -"ampulla", -"amputee", -"ampyx", -"amra", -"amreeta", -"amrita", -"amsath", -"amsel", -"amt", -"amtman", -"amuck", -"amuguis", -"amula", -"amulet", -"amulla", -"amunam", -"amurca", -"amuse", -"amused", -"amusee", -"amuser", -"amusia", -"amusing", -"amusive", -"amutter", -"amuyon", -"amuyong", -"amuze", -"amvis", -"amy", -"amyelia", -"amyelic", -"amygdal", -"amyl", -"amylan", -"amylase", -"amylate", -"amylene", -"amylic", -"amylin", -"amylo", -"amyloid", -"amylom", -"amylon", -"amylose", -"amylum", -"amyous", -"amyrin", -"amyrol", -"amyroot", -"an", -"ana", -"anabata", -"anabo", -"anabong", -"anacara", -"anacard", -"anacid", -"anadem", -"anadrom", -"anaemia", -"anaemic", -"anagap", -"anagep", -"anagoge", -"anagogy", -"anagram", -"anagua", -"anahau", -"anal", -"analav", -"analgen", -"analgia", -"analgic", -"anally", -"analogy", -"analyse", -"analyst", -"analyze", -"anam", -"anama", -"anamite", -"anan", -"anana", -"ananas", -"ananda", -"ananym", -"anaphia", -"anapnea", -"anapsid", -"anaqua", -"anarch", -"anarchy", -"anareta", -"anarya", -"anatase", -"anatifa", -"anatine", -"anatomy", -"anatox", -"anatron", -"anaudia", -"anaxial", -"anaxon", -"anaxone", -"anay", -"anba", -"anbury", -"anchor", -"anchovy", -"ancient", -"ancile", -"ancilla", -"ancon", -"anconad", -"anconal", -"ancone", -"ancony", -"ancora", -"ancoral", -"and", -"anda", -"andante", -"andirin", -"andiron", -"andric", -"android", -"androl", -"andron", -"anear", -"aneath", -"anele", -"anemia", -"anemic", -"anemone", -"anemony", -"anend", -"anenst", -"anent", -"anepia", -"anergia", -"anergic", -"anergy", -"anerly", -"aneroid", -"anes", -"anesis", -"aneuria", -"aneuric", -"aneurin", -"anew", -"angaria", -"angary", -"angekok", -"angel", -"angelet", -"angelic", -"angelin", -"angelot", -"anger", -"angerly", -"angeyok", -"angico", -"angild", -"angili", -"angina", -"anginal", -"angioid", -"angioma", -"angle", -"angled", -"angler", -"angling", -"angloid", -"ango", -"angolar", -"angor", -"angrily", -"angrite", -"angry", -"angst", -"angster", -"anguid", -"anguine", -"anguis", -"anguish", -"angula", -"angular", -"anguria", -"anhang", -"anhima", -"anhinga", -"ani", -"anicut", -"anidian", -"aniente", -"anigh", -"anight", -"anights", -"anil", -"anilao", -"anilau", -"anile", -"anilic", -"anilid", -"anilide", -"aniline", -"anility", -"anilla", -"anima", -"animal", -"animate", -"anime", -"animi", -"animism", -"animist", -"animize", -"animous", -"animus", -"anion", -"anionic", -"anis", -"anisal", -"anisate", -"anise", -"aniseed", -"anisic", -"anisil", -"anisoin", -"anisole", -"anisoyl", -"anisum", -"anisyl", -"anither", -"anjan", -"ankee", -"anker", -"ankh", -"ankle", -"anklet", -"anklong", -"ankus", -"ankusha", -"anlace", -"anlaut", -"ann", -"anna", -"annal", -"annale", -"annals", -"annat", -"annates", -"annatto", -"anneal", -"annelid", -"annet", -"annex", -"annexa", -"annexal", -"annexer", -"annite", -"annona", -"annoy", -"annoyer", -"annual", -"annuary", -"annuent", -"annuity", -"annul", -"annular", -"annulet", -"annulus", -"anoa", -"anodal", -"anode", -"anodic", -"anodize", -"anodos", -"anodyne", -"anoesia", -"anoesis", -"anoetic", -"anoil", -"anoine", -"anoint", -"anole", -"anoli", -"anolian", -"anolyte", -"anomaly", -"anomite", -"anomy", -"anon", -"anonang", -"anonol", -"anonym", -"anonyma", -"anopia", -"anopsia", -"anorak", -"anorexy", -"anormal", -"anorth", -"anosmia", -"anosmic", -"another", -"anotia", -"anotta", -"anotto", -"anotus", -"anounou", -"anoxia", -"anoxic", -"ansa", -"ansar", -"ansate", -"ansu", -"answer", -"ant", -"anta", -"antacid", -"antal", -"antapex", -"antdom", -"ante", -"anteact", -"anteal", -"antefix", -"antenna", -"antes", -"antewar", -"anthela", -"anthem", -"anthema", -"anthemy", -"anther", -"anthill", -"anthine", -"anthoid", -"anthood", -"anthrax", -"anthrol", -"anthryl", -"anti", -"antiae", -"antiar", -"antic", -"antical", -"anticly", -"anticor", -"anticum", -"antifat", -"antigen", -"antigod", -"antihum", -"antiqua", -"antique", -"antired", -"antirun", -"antisun", -"antitax", -"antiwar", -"antiwit", -"antler", -"antlia", -"antling", -"antoeci", -"antonym", -"antra", -"antral", -"antre", -"antrin", -"antrum", -"antship", -"antu", -"antwise", -"anubing", -"anuloma", -"anuran", -"anuria", -"anuric", -"anurous", -"anury", -"anus", -"anusim", -"anvil", -"anxiety", -"anxious", -"any", -"anybody", -"anyhow", -"anyone", -"anyway", -"anyways", -"anywhen", -"anywhy", -"anywise", -"aogiri", -"aonach", -"aorist", -"aorta", -"aortal", -"aortic", -"aortism", -"aosmic", -"aoudad", -"apa", -"apace", -"apache", -"apadana", -"apagoge", -"apaid", -"apalit", -"apandry", -"apar", -"aparejo", -"apart", -"apasote", -"apatan", -"apathic", -"apathy", -"apatite", -"ape", -"apeak", -"apedom", -"apehood", -"apeiron", -"apelet", -"apelike", -"apeling", -"apepsia", -"apepsy", -"apeptic", -"aper", -"aperch", -"aperea", -"apert", -"apertly", -"apery", -"apetaly", -"apex", -"apexed", -"aphagia", -"aphakia", -"aphakic", -"aphasia", -"aphasic", -"aphemia", -"aphemic", -"aphesis", -"apheta", -"aphetic", -"aphid", -"aphides", -"aphidid", -"aphodal", -"aphodus", -"aphonia", -"aphonic", -"aphony", -"aphoria", -"aphotic", -"aphrite", -"aphtha", -"aphthic", -"aphylly", -"aphyric", -"apian", -"apiary", -"apiator", -"apicad", -"apical", -"apices", -"apicula", -"apiece", -"apieces", -"apii", -"apiin", -"apilary", -"apinch", -"aping", -"apinoid", -"apio", -"apioid", -"apiole", -"apiolin", -"apionol", -"apiose", -"apish", -"apishly", -"apism", -"apitong", -"apitpat", -"aplanat", -"aplasia", -"aplenty", -"aplite", -"aplitic", -"aplomb", -"aplome", -"apnea", -"apneal", -"apneic", -"apocarp", -"apocha", -"apocope", -"apod", -"apodal", -"apodan", -"apodema", -"apodeme", -"apodia", -"apodous", -"apogamy", -"apogeal", -"apogean", -"apogee", -"apogeic", -"apogeny", -"apohyal", -"apoise", -"apojove", -"apokrea", -"apolar", -"apology", -"aponia", -"aponic", -"apoop", -"apoplex", -"apopyle", -"aporia", -"aporose", -"aport", -"aposia", -"aposoro", -"apostil", -"apostle", -"apothem", -"apotome", -"apotype", -"apout", -"apozem", -"apozema", -"appall", -"apparel", -"appay", -"appeal", -"appear", -"appease", -"append", -"appet", -"appete", -"applaud", -"apple", -"applied", -"applier", -"applot", -"apply", -"appoint", -"apport", -"appose", -"apposer", -"apprend", -"apprise", -"apprize", -"approof", -"approve", -"appulse", -"apraxia", -"apraxic", -"apricot", -"apriori", -"apron", -"apropos", -"apse", -"apsidal", -"apsides", -"apsis", -"apt", -"apteral", -"apteran", -"aptly", -"aptness", -"aptote", -"aptotic", -"apulse", -"apyonin", -"apyrene", -"apyrexy", -"apyrous", -"aqua", -"aquabib", -"aquage", -"aquaria", -"aquatic", -"aquavit", -"aqueous", -"aquifer", -"aquiver", -"aquo", -"aquose", -"ar", -"ara", -"araba", -"araban", -"arabana", -"arabin", -"arabit", -"arable", -"araca", -"aracari", -"arachic", -"arachin", -"arad", -"arado", -"arain", -"arake", -"araliad", -"aralie", -"aralkyl", -"aramina", -"araneid", -"aranein", -"aranga", -"arango", -"arar", -"arara", -"ararao", -"arariba", -"araroba", -"arati", -"aration", -"aratory", -"arba", -"arbacin", -"arbalo", -"arbiter", -"arbor", -"arboral", -"arbored", -"arboret", -"arbute", -"arbutin", -"arbutus", -"arc", -"arca", -"arcade", -"arcana", -"arcanal", -"arcane", -"arcanum", -"arcate", -"arch", -"archae", -"archaic", -"arche", -"archeal", -"arched", -"archer", -"archery", -"arches", -"archeus", -"archfoe", -"archgod", -"archil", -"arching", -"archive", -"archly", -"archon", -"archont", -"archsee", -"archsin", -"archspy", -"archwag", -"archway", -"archy", -"arcing", -"arcked", -"arcking", -"arctian", -"arctic", -"arctiid", -"arctoid", -"arcual", -"arcuale", -"arcuate", -"arcula", -"ardeb", -"ardella", -"ardency", -"ardent", -"ardish", -"ardoise", -"ardor", -"ardri", -"ardu", -"arduous", -"are", -"area", -"areach", -"aread", -"areal", -"arear", -"areaway", -"arecain", -"ared", -"areek", -"areel", -"arefact", -"areito", -"arena", -"arenae", -"arend", -"areng", -"arenoid", -"arenose", -"arent", -"areola", -"areolar", -"areole", -"areolet", -"arete", -"argal", -"argala", -"argali", -"argans", -"argasid", -"argeers", -"argel", -"argenol", -"argent", -"arghan", -"arghel", -"arghool", -"argil", -"argo", -"argol", -"argolet", -"argon", -"argosy", -"argot", -"argotic", -"argue", -"arguer", -"argufy", -"argute", -"argyria", -"argyric", -"arhar", -"arhat", -"aria", -"aribine", -"aricine", -"arid", -"aridge", -"aridian", -"aridity", -"aridly", -"ariel", -"arienzo", -"arietta", -"aright", -"arigue", -"aril", -"ariled", -"arillus", -"ariose", -"arioso", -"ariot", -"aripple", -"arisard", -"arise", -"arisen", -"arist", -"arista", -"arite", -"arjun", -"ark", -"arkite", -"arkose", -"arkosic", -"arles", -"arm", -"armada", -"armbone", -"armed", -"armer", -"armet", -"armful", -"armhole", -"armhoop", -"armied", -"armiger", -"armil", -"armilla", -"arming", -"armless", -"armlet", -"armload", -"armoire", -"armor", -"armored", -"armorer", -"armory", -"armpit", -"armrack", -"armrest", -"arms", -"armscye", -"armure", -"army", -"arn", -"arna", -"arnee", -"arni", -"arnica", -"arnotta", -"arnotto", -"arnut", -"aroar", -"aroast", -"arock", -"aroeira", -"aroid", -"aroint", -"arolium", -"arolla", -"aroma", -"aroon", -"arose", -"around", -"arousal", -"arouse", -"arouser", -"arow", -"aroxyl", -"arpen", -"arpent", -"arrack", -"arrah", -"arraign", -"arrame", -"arrange", -"arrant", -"arras", -"arrased", -"arratel", -"arrau", -"array", -"arrayal", -"arrayer", -"arrear", -"arrect", -"arrent", -"arrest", -"arriage", -"arriba", -"arride", -"arridge", -"arrie", -"arriere", -"arrimby", -"arris", -"arrish", -"arrival", -"arrive", -"arriver", -"arroba", -"arrope", -"arrow", -"arrowed", -"arrowy", -"arroyo", -"arse", -"arsenal", -"arsenic", -"arseno", -"arsenyl", -"arses", -"arsheen", -"arshin", -"arshine", -"arsine", -"arsinic", -"arsino", -"arsis", -"arsle", -"arsoite", -"arson", -"arsonic", -"arsono", -"arsyl", -"art", -"artaba", -"artabe", -"artal", -"artar", -"artel", -"arterin", -"artery", -"artful", -"artha", -"arthel", -"arthral", -"artiad", -"article", -"artisan", -"artist", -"artiste", -"artless", -"artlet", -"artlike", -"artware", -"arty", -"aru", -"arui", -"aruke", -"arumin", -"arupa", -"arusa", -"arusha", -"arustle", -"arval", -"arvel", -"arx", -"ary", -"aryl", -"arylate", -"arzan", -"arzun", -"as", -"asaddle", -"asak", -"asale", -"asana", -"asaphia", -"asaphid", -"asaprol", -"asarite", -"asaron", -"asarone", -"asbest", -"asbolin", -"ascan", -"ascare", -"ascarid", -"ascaron", -"ascend", -"ascent", -"ascetic", -"ascham", -"asci", -"ascian", -"ascii", -"ascites", -"ascitic", -"asclent", -"ascoma", -"ascon", -"ascot", -"ascribe", -"ascript", -"ascry", -"ascula", -"ascus", -"asdic", -"ase", -"asearch", -"aseethe", -"aseity", -"asem", -"asemia", -"asepsis", -"aseptic", -"aseptol", -"asexual", -"ash", -"ashake", -"ashame", -"ashamed", -"ashamnu", -"ashcake", -"ashen", -"asherah", -"ashery", -"ashes", -"ashet", -"ashily", -"ashine", -"ashiver", -"ashkoko", -"ashlar", -"ashless", -"ashling", -"ashman", -"ashore", -"ashpan", -"ashpit", -"ashraf", -"ashrafi", -"ashur", -"ashweed", -"ashwort", -"ashy", -"asialia", -"aside", -"asideu", -"asiento", -"asilid", -"asimen", -"asimmer", -"asinego", -"asinine", -"asitia", -"ask", -"askable", -"askance", -"askant", -"askar", -"askari", -"asker", -"askew", -"askip", -"asklent", -"askos", -"aslant", -"aslaver", -"asleep", -"aslop", -"aslope", -"asmack", -"asmalte", -"asmear", -"asmile", -"asmoke", -"asnort", -"asoak", -"asocial", -"asok", -"asoka", -"asonant", -"asonia", -"asop", -"asor", -"asouth", -"asp", -"aspace", -"aspect", -"aspen", -"asper", -"asperge", -"asperse", -"asphalt", -"asphyxy", -"aspic", -"aspire", -"aspirer", -"aspirin", -"aspish", -"asport", -"aspout", -"asprawl", -"aspread", -"aspring", -"asprout", -"asquare", -"asquat", -"asqueal", -"asquint", -"asquirm", -"ass", -"assacu", -"assagai", -"assai", -"assail", -"assapan", -"assart", -"assary", -"assate", -"assault", -"assaut", -"assay", -"assayer", -"assbaa", -"asse", -"assegai", -"asself", -"assent", -"assert", -"assess", -"asset", -"assets", -"assever", -"asshead", -"assi", -"assify", -"assign", -"assilag", -"assis", -"assise", -"assish", -"assist", -"assize", -"assizer", -"assizes", -"asslike", -"assman", -"assoil", -"assort", -"assuade", -"assuage", -"assume", -"assumed", -"assumer", -"assure", -"assured", -"assurer", -"assurge", -"ast", -"asta", -"astalk", -"astare", -"astart", -"astasia", -"astatic", -"astay", -"asteam", -"asteep", -"asteer", -"asteism", -"astelic", -"astely", -"aster", -"asteria", -"asterin", -"astern", -"astheny", -"asthma", -"asthore", -"astilbe", -"astint", -"astir", -"astite", -"astomia", -"astony", -"astoop", -"astor", -"astound", -"astrain", -"astral", -"astrand", -"astray", -"astream", -"astrer", -"astrict", -"astride", -"astrier", -"astrild", -"astroid", -"astrut", -"astute", -"astylar", -"asudden", -"asunder", -"aswail", -"aswarm", -"asway", -"asweat", -"aswell", -"aswim", -"aswing", -"aswirl", -"aswoon", -"asyla", -"asylum", -"at", -"atabal", -"atabeg", -"atabek", -"atactic", -"atafter", -"ataman", -"atangle", -"atap", -"ataraxy", -"ataunt", -"atavi", -"atavic", -"atavism", -"atavist", -"atavus", -"ataxia", -"ataxic", -"ataxite", -"ataxy", -"atazir", -"atbash", -"ate", -"atebrin", -"atechny", -"ateeter", -"atef", -"atelets", -"atelier", -"atelo", -"ates", -"ateuchi", -"athanor", -"athar", -"atheism", -"atheist", -"atheize", -"athelia", -"athenee", -"athenor", -"atheous", -"athing", -"athirst", -"athlete", -"athodyd", -"athort", -"athrill", -"athrive", -"athrob", -"athrong", -"athwart", -"athymia", -"athymic", -"athymy", -"athyria", -"athyrid", -"atilt", -"atimon", -"atinga", -"atingle", -"atinkle", -"atip", -"atis", -"atlas", -"atlatl", -"atle", -"atlee", -"atloid", -"atma", -"atman", -"atmid", -"atmo", -"atmos", -"atocha", -"atocia", -"atokal", -"atoke", -"atokous", -"atoll", -"atom", -"atomerg", -"atomic", -"atomics", -"atomism", -"atomist", -"atomity", -"atomize", -"atomy", -"atonal", -"atone", -"atoner", -"atonia", -"atonic", -"atony", -"atop", -"atophan", -"atopic", -"atopite", -"atopy", -"atour", -"atoxic", -"atoxyl", -"atrail", -"atrepsy", -"atresia", -"atresic", -"atresy", -"atretic", -"atria", -"atrial", -"atrip", -"atrium", -"atrocha", -"atropal", -"atrophy", -"atropia", -"atropic", -"atrous", -"atry", -"atta", -"attacco", -"attach", -"attache", -"attack", -"attacus", -"attagen", -"attain", -"attaint", -"attaleh", -"attar", -"attask", -"attempt", -"attend", -"attent", -"atter", -"attern", -"attery", -"attest", -"attic", -"attid", -"attinge", -"attire", -"attired", -"attirer", -"attorn", -"attract", -"attrap", -"attrist", -"attrite", -"attune", -"atule", -"atumble", -"atune", -"atwain", -"atweel", -"atween", -"atwin", -"atwirl", -"atwist", -"atwitch", -"atwixt", -"atwo", -"atypic", -"atypy", -"auantic", -"aube", -"aubrite", -"auburn", -"auca", -"auchlet", -"auction", -"aucuba", -"audible", -"audibly", -"audient", -"audile", -"audio", -"audion", -"audit", -"auditor", -"auge", -"augen", -"augend", -"auger", -"augerer", -"augh", -"aught", -"augite", -"augitic", -"augment", -"augur", -"augural", -"augury", -"august", -"auh", -"auhuhu", -"auk", -"auklet", -"aula", -"aulae", -"auld", -"auletai", -"aulete", -"auletes", -"auletic", -"aulic", -"auloi", -"aulos", -"aulu", -"aum", -"aumaga", -"aumail", -"aumbry", -"aumery", -"aumil", -"aumous", -"aumrie", -"auncel", -"aune", -"aunt", -"auntie", -"auntish", -"auntly", -"aupaka", -"aura", -"aurae", -"aural", -"aurally", -"aurar", -"aurate", -"aurated", -"aureate", -"aureity", -"aurelia", -"aureola", -"aureole", -"aureous", -"auresca", -"aureus", -"auric", -"auricle", -"auride", -"aurific", -"aurify", -"aurigal", -"aurin", -"aurir", -"aurist", -"aurite", -"aurochs", -"auronal", -"aurora", -"aurorae", -"auroral", -"aurore", -"aurous", -"aurum", -"aurure", -"auryl", -"auscult", -"auslaut", -"auspex", -"auspice", -"auspicy", -"austere", -"austral", -"ausu", -"ausubo", -"autarch", -"autarky", -"aute", -"autecy", -"autem", -"author", -"autism", -"autist", -"auto", -"autobus", -"autocab", -"autocar", -"autoecy", -"autoist", -"automa", -"automat", -"autonym", -"autopsy", -"autumn", -"auxesis", -"auxetic", -"auxin", -"auxinic", -"auxotox", -"ava", -"avadana", -"avahi", -"avail", -"aval", -"avalent", -"avania", -"avarice", -"avast", -"avaunt", -"ave", -"avellan", -"aveloz", -"avenage", -"avener", -"avenge", -"avenger", -"avenin", -"avenous", -"avens", -"avenue", -"aver", -"avera", -"average", -"averah", -"averil", -"averin", -"averral", -"averse", -"avert", -"averted", -"averter", -"avian", -"aviary", -"aviate", -"aviatic", -"aviator", -"avichi", -"avicide", -"avick", -"avid", -"avidity", -"avidly", -"avidous", -"avidya", -"avigate", -"avijja", -"avine", -"aviso", -"avital", -"avitic", -"avives", -"avo", -"avocado", -"avocate", -"avocet", -"avodire", -"avoid", -"avoider", -"avolate", -"avouch", -"avow", -"avowal", -"avowant", -"avowed", -"avower", -"avowry", -"avoyer", -"avulse", -"aw", -"awa", -"awabi", -"awaft", -"awag", -"await", -"awaiter", -"awake", -"awaken", -"awald", -"awalim", -"awalt", -"awane", -"awapuhi", -"award", -"awarder", -"aware", -"awash", -"awaste", -"awat", -"awatch", -"awater", -"awave", -"away", -"awber", -"awd", -"awe", -"aweary", -"aweband", -"awee", -"aweek", -"aweel", -"aweigh", -"awesome", -"awest", -"aweto", -"awfu", -"awful", -"awfully", -"awheel", -"awheft", -"awhet", -"awhile", -"awhir", -"awhirl", -"awide", -"awiggle", -"awin", -"awing", -"awink", -"awiwi", -"awkward", -"awl", -"awless", -"awlwort", -"awmous", -"awn", -"awned", -"awner", -"awning", -"awnless", -"awnlike", -"awny", -"awoke", -"awork", -"awreck", -"awrist", -"awrong", -"awry", -"ax", -"axal", -"axe", -"axed", -"axenic", -"axes", -"axfetch", -"axhead", -"axial", -"axially", -"axiate", -"axiform", -"axil", -"axile", -"axilla", -"axillae", -"axillar", -"axine", -"axinite", -"axiom", -"axion", -"axis", -"axised", -"axite", -"axle", -"axled", -"axmaker", -"axman", -"axogamy", -"axoid", -"axolotl", -"axon", -"axonal", -"axonost", -"axseed", -"axstone", -"axtree", -"axunge", -"axweed", -"axwise", -"axwort", -"ay", -"ayah", -"aye", -"ayelp", -"ayin", -"ayless", -"aylet", -"ayllu", -"ayond", -"ayont", -"ayous", -"ayu", -"azafrin", -"azalea", -"azarole", -"azelaic", -"azelate", -"azide", -"azilut", -"azimene", -"azimide", -"azimine", -"azimino", -"azimuth", -"azine", -"aziola", -"azo", -"azoch", -"azofier", -"azofy", -"azoic", -"azole", -"azon", -"azonal", -"azonic", -"azonium", -"azophen", -"azorite", -"azotate", -"azote", -"azoted", -"azoth", -"azotic", -"azotine", -"azotite", -"azotize", -"azotous", -"azox", -"azoxime", -"azoxine", -"azoxy", -"azteca", -"azulene", -"azulite", -"azulmic", -"azumbre", -"azure", -"azurean", -"azured", -"azurine", -"azurite", -"azurous", -"azury", -"azygos", -"azygous", -"azyme", -"azymite", -"azymous", -"b", -"ba", -"baa", -"baal", -"baar", -"baba", -"babai", -"babasco", -"babassu", -"babbitt", -"babble", -"babbler", -"babbly", -"babby", -"babe", -"babelet", -"babery", -"babiche", -"babied", -"babish", -"bablah", -"babloh", -"baboen", -"baboo", -"baboon", -"baboot", -"babroot", -"babu", -"babudom", -"babuina", -"babuism", -"babul", -"baby", -"babydom", -"babyish", -"babyism", -"bac", -"bacaba", -"bacach", -"bacalao", -"bacao", -"bacca", -"baccae", -"baccara", -"baccate", -"bacchar", -"bacchic", -"bacchii", -"bach", -"bache", -"bachel", -"bacilli", -"back", -"backage", -"backcap", -"backed", -"backen", -"backer", -"backet", -"backie", -"backing", -"backjaw", -"backlet", -"backlog", -"backrun", -"backsaw", -"backset", -"backup", -"backway", -"baclin", -"bacon", -"baconer", -"bacony", -"bacula", -"bacule", -"baculi", -"baculum", -"baculus", -"bacury", -"bad", -"badan", -"baddish", -"baddock", -"bade", -"badge", -"badger", -"badiaga", -"badian", -"badious", -"badland", -"badly", -"badness", -"bae", -"baetuli", -"baetyl", -"bafaro", -"baff", -"baffeta", -"baffle", -"baffler", -"baffy", -"baft", -"bafta", -"bag", -"baga", -"bagani", -"bagasse", -"bagel", -"bagful", -"baggage", -"baggala", -"bagged", -"bagger", -"baggie", -"baggily", -"bagging", -"baggit", -"baggy", -"baglike", -"bagman", -"bagnio", -"bagnut", -"bago", -"bagonet", -"bagpipe", -"bagre", -"bagreef", -"bagroom", -"bagwig", -"bagworm", -"bagwyn", -"bah", -"bahan", -"bahar", -"bahay", -"bahera", -"bahisti", -"bahnung", -"baho", -"bahoe", -"bahoo", -"baht", -"bahur", -"bahut", -"baignet", -"baikie", -"bail", -"bailage", -"bailee", -"bailer", -"bailey", -"bailie", -"bailiff", -"bailor", -"bain", -"bainie", -"baioc", -"baiocco", -"bairagi", -"bairn", -"bairnie", -"bairnly", -"baister", -"bait", -"baiter", -"baith", -"baittle", -"baize", -"bajada", -"bajan", -"bajra", -"bajree", -"bajri", -"bajury", -"baka", -"bakal", -"bake", -"baked", -"baken", -"bakepan", -"baker", -"bakerly", -"bakery", -"bakie", -"baking", -"bakli", -"baktun", -"baku", -"bakula", -"bal", -"balafo", -"balagan", -"balai", -"balance", -"balanic", -"balanid", -"balao", -"balas", -"balata", -"balboa", -"balcony", -"bald", -"balden", -"balder", -"baldish", -"baldly", -"baldrib", -"baldric", -"baldy", -"bale", -"baleen", -"baleful", -"balei", -"baleise", -"baler", -"balete", -"bali", -"baline", -"balita", -"balk", -"balker", -"balky", -"ball", -"ballad", -"ballade", -"ballam", -"ballan", -"ballant", -"ballast", -"ballata", -"ballate", -"balldom", -"balled", -"baller", -"ballet", -"balli", -"ballist", -"ballium", -"balloon", -"ballot", -"ballow", -"ballup", -"bally", -"balm", -"balmily", -"balmony", -"balmy", -"balneal", -"balonea", -"baloney", -"baloo", -"balow", -"balsa", -"balsam", -"balsamo", -"balsamy", -"baltei", -"balter", -"balteus", -"balu", -"balut", -"balza", -"bam", -"bamban", -"bambini", -"bambino", -"bamboo", -"bamoth", -"ban", -"banaba", -"banago", -"banak", -"banal", -"banally", -"banana", -"banat", -"banc", -"banca", -"bancal", -"banchi", -"banco", -"bancus", -"band", -"banda", -"bandage", -"bandaka", -"bandala", -"bandar", -"bandbox", -"bande", -"bandeau", -"banded", -"bander", -"bandhu", -"bandi", -"bandie", -"banding", -"bandit", -"bandle", -"bandlet", -"bandman", -"bando", -"bandog", -"bandore", -"bandrol", -"bandy", -"bane", -"baneful", -"bang", -"banga", -"bange", -"banger", -"banghy", -"banging", -"bangkok", -"bangle", -"bangled", -"bani", -"banian", -"banig", -"banilad", -"banish", -"baniwa", -"baniya", -"banjo", -"banjore", -"banjuke", -"bank", -"banked", -"banker", -"bankera", -"banket", -"banking", -"bankman", -"banky", -"banner", -"bannet", -"banning", -"bannock", -"banns", -"bannut", -"banquet", -"banshee", -"bant", -"bantam", -"bantay", -"banteng", -"banter", -"bantery", -"banty", -"banuyo", -"banya", -"banyan", -"banzai", -"baobab", -"bap", -"baptism", -"baptize", -"bar", -"bara", -"barad", -"barauna", -"barb", -"barbal", -"barbary", -"barbas", -"barbate", -"barbe", -"barbed", -"barbel", -"barber", -"barbet", -"barbion", -"barblet", -"barbone", -"barbudo", -"barbule", -"bard", -"bardane", -"bardash", -"bardel", -"bardess", -"bardic", -"bardie", -"bardily", -"barding", -"bardish", -"bardism", -"bardlet", -"bardo", -"bardy", -"bare", -"bareca", -"barefit", -"barely", -"barer", -"baresma", -"baretta", -"barff", -"barfish", -"barfly", -"barful", -"bargain", -"barge", -"bargee", -"bargeer", -"barger", -"bargh", -"bargham", -"bari", -"baria", -"baric", -"barid", -"barie", -"barile", -"barilla", -"baring", -"baris", -"barish", -"barit", -"barite", -"barium", -"bark", -"barken", -"barker", -"barkery", -"barkey", -"barkhan", -"barking", -"barkle", -"barky", -"barless", -"barley", -"barling", -"barlock", -"barlow", -"barm", -"barmaid", -"barman", -"barmkin", -"barmote", -"barmy", -"barn", -"barnard", -"barney", -"barnful", -"barnman", -"barny", -"baroi", -"barolo", -"baron", -"baronet", -"barong", -"baronry", -"barony", -"baroque", -"baroto", -"barpost", -"barra", -"barrack", -"barrad", -"barrage", -"barras", -"barred", -"barrel", -"barren", -"barrer", -"barret", -"barrico", -"barrier", -"barring", -"barrio", -"barroom", -"barrow", -"barruly", -"barry", -"barse", -"barsom", -"barter", -"barth", -"barton", -"baru", -"baruria", -"barvel", -"barwal", -"barway", -"barways", -"barwise", -"barwood", -"barye", -"baryta", -"barytes", -"barytic", -"baryton", -"bas", -"basal", -"basale", -"basalia", -"basally", -"basalt", -"basaree", -"bascule", -"base", -"based", -"basely", -"baseman", -"basenji", -"bases", -"bash", -"bashaw", -"bashful", -"bashlyk", -"basial", -"basiate", -"basic", -"basidia", -"basify", -"basil", -"basilar", -"basilic", -"basin", -"basined", -"basinet", -"basion", -"basis", -"bask", -"basker", -"basket", -"basoid", -"bason", -"basos", -"basote", -"basque", -"basqued", -"bass", -"bassan", -"bassara", -"basset", -"bassie", -"bassine", -"bassist", -"basso", -"bassoon", -"bassus", -"bast", -"basta", -"bastard", -"baste", -"basten", -"baster", -"bastide", -"basting", -"bastion", -"bastite", -"basto", -"baston", -"bat", -"bataan", -"batad", -"batakan", -"batara", -"batata", -"batch", -"batcher", -"bate", -"batea", -"bateau", -"bateaux", -"bated", -"batel", -"bateman", -"bater", -"batfish", -"batfowl", -"bath", -"bathe", -"bather", -"bathic", -"bathing", -"bathman", -"bathmic", -"bathos", -"bathtub", -"bathyal", -"batik", -"batiker", -"bating", -"batino", -"batiste", -"batlan", -"batlike", -"batling", -"batlon", -"batman", -"batoid", -"baton", -"batonne", -"bats", -"batsman", -"batster", -"batt", -"batta", -"battel", -"batten", -"batter", -"battery", -"battik", -"batting", -"battish", -"battle", -"battled", -"battler", -"battue", -"batty", -"batule", -"batwing", -"batz", -"batzen", -"bauble", -"bauch", -"bauchle", -"bauckie", -"baud", -"baul", -"bauleah", -"baun", -"bauno", -"bauson", -"bausond", -"bauta", -"bauxite", -"bavaroy", -"bavary", -"bavian", -"baviere", -"bavin", -"bavoso", -"baw", -"bawbee", -"bawcock", -"bawd", -"bawdily", -"bawdry", -"bawl", -"bawler", -"bawley", -"bawn", -"bawtie", -"baxter", -"baxtone", -"bay", -"baya", -"bayal", -"bayamo", -"bayard", -"baybolt", -"baybush", -"baycuru", -"bayed", -"bayeta", -"baygall", -"bayhead", -"bayish", -"baylet", -"baylike", -"bayman", -"bayness", -"bayok", -"bayonet", -"bayou", -"baywood", -"bazaar", -"baze", -"bazoo", -"bazooka", -"bazzite", -"bdellid", -"be", -"beach", -"beached", -"beachy", -"beacon", -"bead", -"beaded", -"beader", -"beadily", -"beading", -"beadle", -"beadlet", -"beadman", -"beadrow", -"beady", -"beagle", -"beak", -"beaked", -"beaker", -"beakful", -"beaky", -"beal", -"beala", -"bealing", -"beam", -"beamage", -"beamed", -"beamer", -"beamful", -"beamily", -"beaming", -"beamish", -"beamlet", -"beamman", -"beamy", -"bean", -"beanbag", -"beancod", -"beanery", -"beanie", -"beano", -"beant", -"beany", -"bear", -"beard", -"bearded", -"bearder", -"beardie", -"beardom", -"beardy", -"bearer", -"bearess", -"bearing", -"bearish", -"bearlet", -"bearm", -"beast", -"beastie", -"beastly", -"beat", -"beata", -"beatae", -"beatee", -"beaten", -"beater", -"beath", -"beatify", -"beating", -"beatus", -"beau", -"beaufin", -"beauish", -"beauism", -"beauti", -"beauty", -"beaux", -"beaver", -"beavery", -"beback", -"bebait", -"bebang", -"bebar", -"bebaron", -"bebaste", -"bebat", -"bebathe", -"bebay", -"bebeast", -"bebed", -"bebeeru", -"bebilya", -"bebite", -"beblain", -"beblear", -"bebled", -"bebless", -"beblood", -"bebloom", -"bebog", -"bebop", -"beboss", -"bebotch", -"bebrave", -"bebrine", -"bebrush", -"bebump", -"bebusy", -"becall", -"becalm", -"becap", -"becard", -"becarve", -"becater", -"because", -"becense", -"bechalk", -"becharm", -"bechase", -"becheck", -"becher", -"bechern", -"bechirp", -"becivet", -"beck", -"becker", -"becket", -"beckon", -"beclad", -"beclang", -"beclart", -"beclasp", -"beclaw", -"becloak", -"beclog", -"becloud", -"beclout", -"beclown", -"becolme", -"becolor", -"become", -"becomes", -"becomma", -"becoom", -"becost", -"becovet", -"becram", -"becramp", -"becrawl", -"becreep", -"becrime", -"becroak", -"becross", -"becrowd", -"becrown", -"becrush", -"becrust", -"becry", -"becuiba", -"becuna", -"becurl", -"becurry", -"becurse", -"becut", -"bed", -"bedad", -"bedamn", -"bedamp", -"bedare", -"bedark", -"bedash", -"bedaub", -"bedawn", -"beday", -"bedaze", -"bedbug", -"bedcap", -"bedcase", -"bedcord", -"bedded", -"bedder", -"bedding", -"bedead", -"bedeaf", -"bedebt", -"bedeck", -"bedel", -"beden", -"bedene", -"bedevil", -"bedew", -"bedewer", -"bedfast", -"bedfoot", -"bedgery", -"bedgoer", -"bedgown", -"bedight", -"bedikah", -"bedim", -"bedin", -"bedip", -"bedirt", -"bedirty", -"bedizen", -"bedkey", -"bedlam", -"bedlar", -"bedless", -"bedlids", -"bedman", -"bedmate", -"bedog", -"bedolt", -"bedot", -"bedote", -"bedouse", -"bedown", -"bedoyo", -"bedpan", -"bedpost", -"bedrail", -"bedral", -"bedrape", -"bedress", -"bedrid", -"bedrift", -"bedrip", -"bedrock", -"bedroll", -"bedroom", -"bedrop", -"bedrown", -"bedrug", -"bedsick", -"bedside", -"bedsite", -"bedsock", -"bedsore", -"bedtick", -"bedtime", -"bedub", -"beduck", -"beduke", -"bedull", -"bedumb", -"bedunce", -"bedunch", -"bedung", -"bedur", -"bedusk", -"bedust", -"bedwarf", -"bedway", -"bedways", -"bedwell", -"bedye", -"bee", -"beearn", -"beech", -"beechen", -"beechy", -"beedged", -"beedom", -"beef", -"beefer", -"beefily", -"beefin", -"beefish", -"beefy", -"beehead", -"beeherd", -"beehive", -"beeish", -"beek", -"beekite", -"beelbow", -"beelike", -"beeline", -"beelol", -"beeman", -"been", -"beennut", -"beer", -"beerage", -"beerily", -"beerish", -"beery", -"bees", -"beest", -"beeswax", -"beet", -"beeth", -"beetle", -"beetled", -"beetler", -"beety", -"beeve", -"beevish", -"beeware", -"beeway", -"beeweed", -"beewise", -"beewort", -"befall", -"befame", -"befan", -"befancy", -"befavor", -"befilch", -"befile", -"befilth", -"befire", -"befist", -"befit", -"beflag", -"beflap", -"beflea", -"befleck", -"beflour", -"beflout", -"beflum", -"befoam", -"befog", -"befool", -"befop", -"before", -"befoul", -"befret", -"befrill", -"befriz", -"befume", -"beg", -"begad", -"begall", -"begani", -"begar", -"begari", -"begash", -"begat", -"begaud", -"begaudy", -"begay", -"begaze", -"begeck", -"begem", -"beget", -"beggar", -"beggary", -"begging", -"begift", -"begild", -"begin", -"begird", -"beglad", -"beglare", -"beglic", -"beglide", -"begloom", -"begloze", -"begluc", -"beglue", -"begnaw", -"bego", -"begob", -"begobs", -"begohm", -"begone", -"begonia", -"begorra", -"begorry", -"begoud", -"begowk", -"begrace", -"begrain", -"begrave", -"begray", -"begreen", -"begrett", -"begrim", -"begrime", -"begroan", -"begrown", -"beguard", -"beguess", -"beguile", -"beguine", -"begulf", -"begum", -"begun", -"begunk", -"begut", -"behale", -"behalf", -"behap", -"behave", -"behead", -"behear", -"behears", -"behedge", -"beheld", -"behelp", -"behen", -"behenic", -"behest", -"behind", -"behint", -"behn", -"behold", -"behoney", -"behoof", -"behoot", -"behoove", -"behorn", -"behowl", -"behung", -"behymn", -"beice", -"beige", -"being", -"beinked", -"beira", -"beisa", -"bejade", -"bejan", -"bejant", -"bejazz", -"bejel", -"bejewel", -"bejig", -"bekah", -"bekick", -"beking", -"bekiss", -"bekko", -"beknave", -"beknit", -"beknow", -"beknown", -"bel", -"bela", -"belabor", -"belaced", -"beladle", -"belady", -"belage", -"belah", -"belam", -"belanda", -"belar", -"belard", -"belash", -"belate", -"belated", -"belaud", -"belay", -"belayer", -"belch", -"belcher", -"beld", -"beldam", -"beleaf", -"beleap", -"beleave", -"belee", -"belfry", -"belga", -"belibel", -"belick", -"belie", -"belief", -"belier", -"believe", -"belight", -"beliked", -"belion", -"belite", -"belive", -"bell", -"bellboy", -"belle", -"belled", -"bellhop", -"bellied", -"belling", -"bellite", -"bellman", -"bellote", -"bellow", -"bellows", -"belly", -"bellyer", -"beloam", -"beloid", -"belong", -"belonid", -"belord", -"belout", -"belove", -"beloved", -"below", -"belsire", -"belt", -"belted", -"belter", -"beltie", -"beltine", -"belting", -"beltman", -"belton", -"beluga", -"belute", -"belve", -"bely", -"belying", -"bema", -"bemad", -"bemadam", -"bemail", -"bemaim", -"beman", -"bemar", -"bemask", -"bemat", -"bemata", -"bemaul", -"bemazed", -"bemeal", -"bemean", -"bemercy", -"bemire", -"bemist", -"bemix", -"bemoan", -"bemoat", -"bemock", -"bemoil", -"bemole", -"bemolt", -"bemoon", -"bemotto", -"bemoult", -"bemouth", -"bemuck", -"bemud", -"bemuddy", -"bemuse", -"bemused", -"bemusk", -"ben", -"bena", -"benab", -"bename", -"benami", -"benasty", -"benben", -"bench", -"bencher", -"benchy", -"bencite", -"bend", -"benda", -"bended", -"bender", -"bending", -"bendlet", -"bendy", -"bene", -"beneath", -"benefic", -"benefit", -"benempt", -"benet", -"beng", -"beni", -"benight", -"benign", -"benison", -"benj", -"benjy", -"benmost", -"benn", -"benne", -"bennel", -"bennet", -"benny", -"beno", -"benorth", -"benote", -"bensel", -"bensh", -"benshea", -"benshee", -"benshi", -"bent", -"bentang", -"benthal", -"benthic", -"benthon", -"benthos", -"benting", -"benty", -"benumb", -"benward", -"benweed", -"benzal", -"benzein", -"benzene", -"benzil", -"benzine", -"benzo", -"benzoic", -"benzoid", -"benzoin", -"benzol", -"benzole", -"benzoxy", -"benzoyl", -"benzyl", -"beode", -"bepaid", -"bepale", -"bepaper", -"beparch", -"beparse", -"bepart", -"bepaste", -"bepat", -"bepaw", -"bepearl", -"bepelt", -"bepen", -"bepewed", -"bepiece", -"bepile", -"bepill", -"bepinch", -"bepity", -"beprank", -"bepray", -"bepress", -"bepride", -"beprose", -"bepuff", -"bepun", -"bequalm", -"bequest", -"bequote", -"ber", -"berain", -"berakah", -"berake", -"berapt", -"berat", -"berate", -"beray", -"bere", -"bereave", -"bereft", -"berend", -"beret", -"berg", -"berger", -"berglet", -"bergut", -"bergy", -"bergylt", -"berhyme", -"beride", -"berinse", -"berith", -"berley", -"berlin", -"berline", -"berm", -"berne", -"berobed", -"beroll", -"beround", -"berret", -"berri", -"berried", -"berrier", -"berry", -"berseem", -"berserk", -"berth", -"berthed", -"berther", -"bertram", -"bertrum", -"berust", -"bervie", -"berycid", -"beryl", -"bes", -"besa", -"besagne", -"besaiel", -"besaint", -"besan", -"besauce", -"bescab", -"bescarf", -"bescent", -"bescorn", -"bescour", -"bescurf", -"beseam", -"besee", -"beseech", -"beseem", -"beseen", -"beset", -"beshade", -"beshag", -"beshake", -"beshame", -"beshear", -"beshell", -"beshine", -"beshlik", -"beshod", -"beshout", -"beshow", -"beshrew", -"beside", -"besides", -"besiege", -"besigh", -"besin", -"besing", -"besiren", -"besit", -"beslab", -"beslap", -"beslash", -"beslave", -"beslime", -"beslow", -"beslur", -"besmear", -"besmell", -"besmile", -"besmoke", -"besmut", -"besnare", -"besneer", -"besnow", -"besnuff", -"besogne", -"besoil", -"besom", -"besomer", -"besoot", -"besot", -"besoul", -"besour", -"bespate", -"bespawl", -"bespeak", -"besped", -"bespeed", -"bespell", -"bespend", -"bespete", -"bespew", -"bespice", -"bespill", -"bespin", -"bespit", -"besplit", -"bespoke", -"bespot", -"bespout", -"bespray", -"bespy", -"besquib", -"besra", -"best", -"bestab", -"bestain", -"bestamp", -"bestar", -"bestare", -"bestay", -"bestead", -"besteer", -"bester", -"bestial", -"bestick", -"bestill", -"bestink", -"bestir", -"bestock", -"bestore", -"bestorm", -"bestove", -"bestow", -"bestraw", -"bestrew", -"bestuck", -"bestud", -"besugar", -"besuit", -"besully", -"beswarm", -"beswim", -"bet", -"beta", -"betag", -"betail", -"betaine", -"betalk", -"betask", -"betaxed", -"betear", -"beteela", -"beteem", -"betel", -"beth", -"bethel", -"bethink", -"bethumb", -"bethump", -"betide", -"betimes", -"betinge", -"betire", -"betis", -"betitle", -"betoil", -"betoken", -"betone", -"betony", -"betoss", -"betowel", -"betrace", -"betrail", -"betrap", -"betray", -"betread", -"betrend", -"betrim", -"betroth", -"betrunk", -"betso", -"betted", -"better", -"betters", -"betting", -"bettong", -"bettor", -"betty", -"betulin", -"betutor", -"between", -"betwine", -"betwit", -"betwixt", -"beveil", -"bevel", -"beveled", -"beveler", -"bevenom", -"bever", -"beverse", -"beveto", -"bevined", -"bevomit", -"bevue", -"bevy", -"bewail", -"bewall", -"beware", -"bewash", -"bewaste", -"bewater", -"beweary", -"beweep", -"bewept", -"bewest", -"bewet", -"bewhig", -"bewhite", -"bewidow", -"bewig", -"bewired", -"bewitch", -"bewith", -"bework", -"beworm", -"beworn", -"beworry", -"bewrap", -"bewray", -"bewreck", -"bewrite", -"bey", -"beydom", -"beylic", -"beyond", -"beyship", -"bezant", -"bezanty", -"bezel", -"bezetta", -"bezique", -"bezoar", -"bezzi", -"bezzle", -"bezzo", -"bhabar", -"bhakta", -"bhakti", -"bhalu", -"bhandar", -"bhang", -"bhangi", -"bhara", -"bharal", -"bhat", -"bhava", -"bheesty", -"bhikku", -"bhikshu", -"bhoosa", -"bhoy", -"bhungi", -"bhut", -"biabo", -"biacid", -"biacuru", -"bialate", -"biallyl", -"bianco", -"biarchy", -"bias", -"biaxal", -"biaxial", -"bib", -"bibasic", -"bibb", -"bibber", -"bibble", -"bibbler", -"bibbons", -"bibcock", -"bibi", -"bibiri", -"bibless", -"biblus", -"bice", -"biceps", -"bicetyl", -"bichir", -"bichord", -"bichy", -"bick", -"bicker", -"bickern", -"bicolor", -"bicone", -"biconic", -"bicorn", -"bicorne", -"bicron", -"bicycle", -"bicyclo", -"bid", -"bidar", -"bidarka", -"bidcock", -"bidder", -"bidding", -"biddy", -"bide", -"bident", -"bider", -"bidet", -"biding", -"bidri", -"biduous", -"bield", -"bieldy", -"bien", -"bienly", -"biennia", -"bier", -"bietle", -"bifara", -"bifer", -"biff", -"biffin", -"bifid", -"bifidly", -"bifilar", -"biflex", -"bifocal", -"bifoil", -"bifold", -"bifolia", -"biform", -"bifront", -"big", -"biga", -"bigamic", -"bigamy", -"bigener", -"bigeye", -"bigg", -"biggah", -"biggen", -"bigger", -"biggest", -"biggin", -"biggish", -"bigha", -"bighead", -"bighorn", -"bight", -"biglot", -"bigness", -"bignou", -"bigot", -"bigoted", -"bigotry", -"bigotty", -"bigroot", -"bigwig", -"bija", -"bijasal", -"bijou", -"bijoux", -"bike", -"bikh", -"bikini", -"bilabe", -"bilalo", -"bilbie", -"bilbo", -"bilby", -"bilch", -"bilcock", -"bildar", -"bilders", -"bile", -"bilge", -"bilgy", -"biliary", -"biliate", -"bilic", -"bilify", -"bilimbi", -"bilio", -"bilious", -"bilith", -"bilk", -"bilker", -"bill", -"billa", -"billbug", -"billed", -"biller", -"billet", -"billety", -"billian", -"billing", -"billion", -"billman", -"billon", -"billot", -"billow", -"billowy", -"billy", -"billyer", -"bilo", -"bilobe", -"bilobed", -"bilsh", -"bilsted", -"biltong", -"bimalar", -"bimanal", -"bimane", -"bimasty", -"bimbil", -"bimeby", -"bimodal", -"bin", -"binal", -"binary", -"binate", -"bind", -"binder", -"bindery", -"binding", -"bindle", -"bindlet", -"bindweb", -"bine", -"bing", -"binge", -"bingey", -"binghi", -"bingle", -"bingo", -"bingy", -"binh", -"bink", -"binman", -"binna", -"binning", -"binnite", -"bino", -"binocle", -"binodal", -"binode", -"binotic", -"binous", -"bint", -"binukau", -"biod", -"biodyne", -"biogen", -"biogeny", -"bioherm", -"biolith", -"biology", -"biome", -"bion", -"bionomy", -"biopsic", -"biopsy", -"bioral", -"biorgan", -"bios", -"biose", -"biosis", -"biota", -"biotaxy", -"biotic", -"biotics", -"biotin", -"biotite", -"biotome", -"biotomy", -"biotope", -"biotype", -"bioxide", -"bipack", -"biparty", -"biped", -"bipedal", -"biphase", -"biplane", -"bipod", -"bipolar", -"biprism", -"biprong", -"birch", -"birchen", -"bird", -"birddom", -"birdeen", -"birder", -"birdie", -"birding", -"birdlet", -"birdman", -"birdy", -"bireme", -"biretta", -"biri", -"biriba", -"birk", -"birken", -"birkie", -"birl", -"birle", -"birler", -"birlie", -"birlinn", -"birma", -"birn", -"birny", -"birr", -"birse", -"birsle", -"birsy", -"birth", -"birthy", -"bis", -"bisabol", -"bisalt", -"biscuit", -"bisect", -"bisexed", -"bisext", -"bishop", -"bismar", -"bismite", -"bismuth", -"bisnaga", -"bison", -"bispore", -"bisque", -"bissext", -"bisson", -"bistate", -"bister", -"bisti", -"bistort", -"bistro", -"bit", -"bitable", -"bitch", -"bite", -"biter", -"biti", -"biting", -"bitless", -"bito", -"bitolyl", -"bitt", -"bitted", -"bitten", -"bitter", -"bittern", -"bitters", -"bittie", -"bittock", -"bitty", -"bitume", -"bitumed", -"bitumen", -"bitwise", -"bityite", -"bitypic", -"biune", -"biunial", -"biunity", -"biurate", -"biurea", -"biuret", -"bivalve", -"bivinyl", -"bivious", -"bivocal", -"bivouac", -"biwa", -"bixin", -"biz", -"bizarre", -"bizet", -"bizonal", -"bizone", -"bizz", -"blab", -"blabber", -"black", -"blacken", -"blacker", -"blackey", -"blackie", -"blackit", -"blackly", -"blacky", -"blad", -"bladder", -"blade", -"bladed", -"blader", -"blading", -"bladish", -"blady", -"blae", -"blaff", -"blaflum", -"blah", -"blain", -"blair", -"blake", -"blame", -"blamed", -"blamer", -"blaming", -"blan", -"blanc", -"blanca", -"blanch", -"blanco", -"bland", -"blanda", -"blandly", -"blank", -"blanked", -"blanket", -"blankly", -"blanky", -"blanque", -"blare", -"blarney", -"blarnid", -"blarny", -"blart", -"blas", -"blase", -"blash", -"blashy", -"blast", -"blasted", -"blaster", -"blastid", -"blastie", -"blasty", -"blat", -"blatant", -"blate", -"blately", -"blather", -"blatta", -"blatter", -"blatti", -"blattid", -"blaubok", -"blaver", -"blaw", -"blawort", -"blay", -"blaze", -"blazer", -"blazing", -"blazon", -"blazy", -"bleach", -"bleak", -"bleakly", -"bleaky", -"blear", -"bleared", -"bleary", -"bleat", -"bleater", -"bleaty", -"bleb", -"blebby", -"bleck", -"blee", -"bleed", -"bleeder", -"bleery", -"bleeze", -"bleezy", -"blellum", -"blemish", -"blench", -"blend", -"blende", -"blended", -"blender", -"blendor", -"blenny", -"blent", -"bleo", -"blesbok", -"bless", -"blessed", -"blesser", -"blest", -"blet", -"blewits", -"blibe", -"blick", -"blickey", -"blight", -"blighty", -"blimp", -"blimy", -"blind", -"blinded", -"blinder", -"blindly", -"blink", -"blinked", -"blinker", -"blinks", -"blinky", -"blinter", -"blintze", -"blip", -"bliss", -"blissom", -"blister", -"blite", -"blithe", -"blithen", -"blither", -"blitter", -"blitz", -"blizz", -"blo", -"bloat", -"bloated", -"bloater", -"blob", -"blobbed", -"blobber", -"blobby", -"bloc", -"block", -"blocked", -"blocker", -"blocky", -"blodite", -"bloke", -"blolly", -"blonde", -"blood", -"blooded", -"bloody", -"blooey", -"bloom", -"bloomer", -"bloomy", -"bloop", -"blooper", -"blore", -"blosmy", -"blossom", -"blot", -"blotch", -"blotchy", -"blotter", -"blotto", -"blotty", -"blouse", -"bloused", -"blout", -"blow", -"blowen", -"blower", -"blowfly", -"blowgun", -"blowing", -"blown", -"blowoff", -"blowout", -"blowth", -"blowup", -"blowy", -"blowze", -"blowzed", -"blowzy", -"blub", -"blubber", -"blucher", -"blue", -"bluecap", -"bluecup", -"blueing", -"blueleg", -"bluely", -"bluer", -"blues", -"bluet", -"bluetop", -"bluey", -"bluff", -"bluffer", -"bluffly", -"bluffy", -"bluggy", -"bluing", -"bluish", -"bluism", -"blunder", -"blunge", -"blunger", -"blunk", -"blunker", -"blunks", -"blunnen", -"blunt", -"blunter", -"bluntie", -"bluntly", -"blup", -"blur", -"blurb", -"blurred", -"blurrer", -"blurry", -"blurt", -"blush", -"blusher", -"blushy", -"bluster", -"blype", -"bo", -"boa", -"boagane", -"boar", -"board", -"boarder", -"boardly", -"boardy", -"boarish", -"boast", -"boaster", -"boat", -"boatage", -"boater", -"boatful", -"boatie", -"boating", -"boatlip", -"boatly", -"boatman", -"bob", -"boba", -"bobac", -"bobbed", -"bobber", -"bobbery", -"bobbin", -"bobbing", -"bobbish", -"bobble", -"bobby", -"bobcat", -"bobcoat", -"bobeche", -"bobfly", -"bobo", -"bobotie", -"bobsled", -"bobstay", -"bobtail", -"bobwood", -"bocal", -"bocardo", -"bocca", -"boccale", -"boccaro", -"bocce", -"boce", -"bocher", -"bock", -"bocking", -"bocoy", -"bod", -"bodach", -"bode", -"bodeful", -"bodega", -"boden", -"boder", -"bodge", -"bodger", -"bodgery", -"bodhi", -"bodice", -"bodiced", -"bodied", -"bodier", -"bodikin", -"bodily", -"boding", -"bodkin", -"bodle", -"bodock", -"body", -"bog", -"boga", -"bogan", -"bogard", -"bogart", -"bogey", -"boggart", -"boggin", -"boggish", -"boggle", -"boggler", -"boggy", -"boghole", -"bogie", -"bogier", -"bogland", -"bogle", -"boglet", -"bogman", -"bogmire", -"bogo", -"bogong", -"bogtrot", -"bogue", -"bogum", -"bogus", -"bogway", -"bogwood", -"bogwort", -"bogy", -"bogydom", -"bogyism", -"bohawn", -"bohea", -"boho", -"bohor", -"bohunk", -"boid", -"boil", -"boiled", -"boiler", -"boilery", -"boiling", -"boily", -"boist", -"bojite", -"bojo", -"bokadam", -"bokard", -"bokark", -"boke", -"bokom", -"bola", -"bolar", -"bold", -"bolden", -"boldine", -"boldly", -"boldo", -"bole", -"boled", -"boleite", -"bolero", -"bolete", -"bolide", -"bolimba", -"bolis", -"bolivar", -"bolivia", -"bolk", -"boll", -"bollard", -"bolled", -"boller", -"bolling", -"bollock", -"bolly", -"bolo", -"boloman", -"boloney", -"bolson", -"bolster", -"bolt", -"boltage", -"boltant", -"boltel", -"bolter", -"bolti", -"bolting", -"bolus", -"bom", -"boma", -"bomb", -"bombard", -"bombast", -"bombed", -"bomber", -"bombo", -"bombola", -"bombous", -"bon", -"bonaci", -"bonagh", -"bonaght", -"bonair", -"bonally", -"bonang", -"bonanza", -"bonasus", -"bonbon", -"bonce", -"bond", -"bondage", -"bondar", -"bonded", -"bonder", -"bonding", -"bondman", -"bonduc", -"bone", -"boned", -"bonedog", -"bonelet", -"boner", -"boneset", -"bonfire", -"bong", -"bongo", -"boniata", -"bonify", -"bonito", -"bonk", -"bonnaz", -"bonnet", -"bonnily", -"bonny", -"bonsai", -"bonus", -"bonxie", -"bony", -"bonze", -"bonzer", -"bonzery", -"bonzian", -"boo", -"boob", -"boobery", -"boobily", -"boobook", -"booby", -"bood", -"boodie", -"boodle", -"boodler", -"boody", -"boof", -"booger", -"boohoo", -"boojum", -"book", -"bookdom", -"booked", -"booker", -"bookery", -"bookful", -"bookie", -"booking", -"bookish", -"bookism", -"booklet", -"bookman", -"booky", -"bool", -"booly", -"boolya", -"boom", -"boomage", -"boomah", -"boomdas", -"boomer", -"booming", -"boomlet", -"boomy", -"boon", -"boonk", -"boopis", -"boor", -"boorish", -"boort", -"boose", -"boost", -"booster", -"boosy", -"boot", -"bootboy", -"booted", -"bootee", -"booter", -"bootery", -"bootful", -"booth", -"boother", -"bootied", -"booting", -"bootleg", -"boots", -"booty", -"booze", -"boozed", -"boozer", -"boozily", -"boozy", -"bop", -"bopeep", -"boppist", -"bopyrid", -"bor", -"bora", -"borable", -"boracic", -"borage", -"borak", -"boral", -"borasca", -"borate", -"borax", -"bord", -"bordage", -"bordar", -"bordel", -"border", -"bordure", -"bore", -"boread", -"boreal", -"borean", -"boredom", -"boree", -"boreen", -"boregat", -"boreism", -"borele", -"borer", -"borg", -"borgh", -"borh", -"boric", -"boride", -"borine", -"boring", -"borish", -"borism", -"bority", -"borize", -"borlase", -"born", -"borne", -"borneol", -"borning", -"bornite", -"bornyl", -"boro", -"boron", -"boronic", -"borough", -"borrel", -"borrow", -"borsch", -"borscht", -"borsht", -"bort", -"bortsch", -"borty", -"bortz", -"borwort", -"boryl", -"borzoi", -"boscage", -"bosch", -"bose", -"boser", -"bosh", -"bosher", -"bosk", -"bosker", -"bosket", -"bosky", -"bosn", -"bosom", -"bosomed", -"bosomer", -"bosomy", -"boss", -"bossage", -"bossdom", -"bossed", -"bosser", -"bosset", -"bossing", -"bossism", -"bosslet", -"bossy", -"boston", -"bostryx", -"bosun", -"bot", -"bota", -"botanic", -"botany", -"botargo", -"botch", -"botched", -"botcher", -"botchka", -"botchy", -"bote", -"botella", -"boterol", -"botfly", -"both", -"bother", -"bothros", -"bothway", -"bothy", -"botonee", -"botong", -"bott", -"bottine", -"bottle", -"bottled", -"bottler", -"bottom", -"botulin", -"bouchal", -"bouche", -"boucher", -"boud", -"boudoir", -"bougar", -"bouge", -"bouget", -"bough", -"boughed", -"bought", -"boughy", -"bougie", -"bouk", -"boukit", -"boulder", -"boule", -"boultel", -"boulter", -"boun", -"bounce", -"bouncer", -"bound", -"bounded", -"bounden", -"bounder", -"boundly", -"bounty", -"bouquet", -"bourbon", -"bourd", -"bourder", -"bourdon", -"bourg", -"bourn", -"bourock", -"bourse", -"bouse", -"bouser", -"bousy", -"bout", -"boutade", -"bouto", -"bouw", -"bovate", -"bovid", -"bovine", -"bovoid", -"bow", -"bowable", -"bowback", -"bowbent", -"bowboy", -"bowed", -"bowel", -"boweled", -"bowels", -"bower", -"bowery", -"bowet", -"bowfin", -"bowhead", -"bowie", -"bowing", -"bowk", -"bowkail", -"bowker", -"bowknot", -"bowl", -"bowla", -"bowleg", -"bowler", -"bowless", -"bowlful", -"bowlike", -"bowline", -"bowling", -"bowls", -"bowly", -"bowman", -"bowpin", -"bowshot", -"bowwood", -"bowwort", -"bowwow", -"bowyer", -"boxbush", -"boxcar", -"boxen", -"boxer", -"boxfish", -"boxful", -"boxhaul", -"boxhead", -"boxing", -"boxlike", -"boxman", -"boxty", -"boxwood", -"boxwork", -"boxy", -"boy", -"boyang", -"boyar", -"boyard", -"boycott", -"boydom", -"boyer", -"boyhood", -"boyish", -"boyism", -"boyla", -"boylike", -"boyship", -"boza", -"bozal", -"bozo", -"bozze", -"bra", -"brab", -"brabant", -"brabble", -"braca", -"braccia", -"braccio", -"brace", -"braced", -"bracer", -"bracero", -"braces", -"brach", -"brachet", -"bracing", -"brack", -"bracken", -"bracker", -"bracket", -"bracky", -"bract", -"bractea", -"bracted", -"brad", -"bradawl", -"bradsot", -"brae", -"braeman", -"brag", -"braggat", -"bragger", -"bragget", -"bragite", -"braid", -"braided", -"braider", -"brail", -"brain", -"brainer", -"brainge", -"brains", -"brainy", -"braird", -"brairo", -"braise", -"brake", -"braker", -"brakie", -"braky", -"bramble", -"brambly", -"bran", -"branch", -"branchi", -"branchy", -"brand", -"branded", -"brander", -"brandy", -"brangle", -"branial", -"brank", -"brankie", -"branle", -"branner", -"branny", -"bransle", -"brant", -"brash", -"brashy", -"brasque", -"brass", -"brasse", -"brasser", -"brasset", -"brassic", -"brassie", -"brassy", -"brat", -"brattie", -"brattle", -"brauna", -"bravade", -"bravado", -"brave", -"bravely", -"braver", -"bravery", -"braving", -"bravish", -"bravo", -"bravura", -"braw", -"brawl", -"brawler", -"brawly", -"brawlys", -"brawn", -"brawned", -"brawner", -"brawny", -"braws", -"braxy", -"bray", -"brayer", -"brayera", -"braza", -"braze", -"brazen", -"brazer", -"brazera", -"brazier", -"brazil", -"breach", -"breachy", -"bread", -"breaden", -"breadth", -"breaghe", -"break", -"breakax", -"breaker", -"breakup", -"bream", -"breards", -"breast", -"breath", -"breathe", -"breathy", -"breba", -"breccia", -"brecham", -"breck", -"brecken", -"bred", -"brede", -"bredi", -"bree", -"breech", -"breed", -"breeder", -"breedy", -"breek", -"breeze", -"breezy", -"bregma", -"brehon", -"brei", -"brekkle", -"brelaw", -"breme", -"bremely", -"brent", -"brephic", -"bret", -"breth", -"brett", -"breva", -"breve", -"brevet", -"brevier", -"brevit", -"brevity", -"brew", -"brewage", -"brewer", -"brewery", -"brewing", -"brewis", -"brewst", -"brey", -"briar", -"bribe", -"bribee", -"briber", -"bribery", -"brichen", -"brick", -"brickel", -"bricken", -"brickle", -"brickly", -"bricky", -"bricole", -"bridal", -"bridale", -"bride", -"bridely", -"bridge", -"bridged", -"bridger", -"bridle", -"bridled", -"bridler", -"bridoon", -"brief", -"briefly", -"briefs", -"brier", -"briered", -"briery", -"brieve", -"brig", -"brigade", -"brigand", -"bright", -"brill", -"brills", -"brim", -"brimful", -"briming", -"brimmed", -"brimmer", -"brin", -"brine", -"briner", -"bring", -"bringal", -"bringer", -"brinish", -"brinjal", -"brink", -"briny", -"brioche", -"brique", -"brisk", -"brisken", -"brisket", -"briskly", -"brisque", -"briss", -"bristle", -"bristly", -"brisure", -"brit", -"brith", -"brither", -"britska", -"britten", -"brittle", -"brizz", -"broach", -"broad", -"broadax", -"broaden", -"broadly", -"brob", -"brocade", -"brocard", -"broch", -"brochan", -"broche", -"brocho", -"brock", -"brocked", -"brocket", -"brockle", -"brod", -"brodder", -"brog", -"brogan", -"brogger", -"broggle", -"brogue", -"broguer", -"broider", -"broigne", -"broil", -"broiler", -"brokage", -"broke", -"broken", -"broker", -"broking", -"brolga", -"broll", -"brolly", -"broma", -"bromal", -"bromate", -"brome", -"bromic", -"bromide", -"bromine", -"bromism", -"bromite", -"bromize", -"bromoil", -"bromol", -"bromous", -"bronc", -"bronchi", -"bronco", -"bronk", -"bronze", -"bronzed", -"bronzen", -"bronzer", -"bronzy", -"broo", -"brooch", -"brood", -"brooder", -"broody", -"brook", -"brooked", -"brookie", -"brooky", -"brool", -"broom", -"broomer", -"broomy", -"broon", -"broose", -"brose", -"brosot", -"brosy", -"brot", -"brotan", -"brotany", -"broth", -"brothel", -"brother", -"brothy", -"brough", -"brought", -"brow", -"browden", -"browed", -"browis", -"browman", -"brown", -"browner", -"brownie", -"brownly", -"browny", -"browse", -"browser", -"browst", -"bruang", -"brucia", -"brucina", -"brucine", -"brucite", -"bruckle", -"brugh", -"bruin", -"bruise", -"bruiser", -"bruit", -"bruiter", -"bruke", -"brulee", -"brulyie", -"brumal", -"brumby", -"brume", -"brumous", -"brunch", -"brunet", -"brunt", -"bruscus", -"brush", -"brushed", -"brusher", -"brushes", -"brushet", -"brushy", -"brusque", -"brustle", -"brut", -"brutage", -"brutal", -"brute", -"brutely", -"brutify", -"bruting", -"brutish", -"brutism", -"brutter", -"bruzz", -"bryonin", -"bryony", -"bu", -"bual", -"buaze", -"bub", -"buba", -"bubal", -"bubalis", -"bubble", -"bubbler", -"bubbly", -"bubby", -"bubinga", -"bubo", -"buboed", -"bubonic", -"bubukle", -"bucare", -"bucca", -"buccal", -"buccan", -"buccate", -"buccina", -"buccula", -"buchite", -"buchu", -"buck", -"bucked", -"buckeen", -"bucker", -"bucket", -"buckety", -"buckeye", -"buckie", -"bucking", -"buckish", -"buckle", -"buckled", -"buckler", -"bucklum", -"bucko", -"buckpot", -"buckra", -"buckram", -"bucksaw", -"bucky", -"bucolic", -"bucrane", -"bud", -"buda", -"buddage", -"budder", -"buddhi", -"budding", -"buddle", -"buddler", -"buddy", -"budge", -"budger", -"budget", -"budless", -"budlet", -"budlike", -"budmash", -"budtime", -"budwood", -"budworm", -"budzat", -"bufagin", -"buff", -"buffalo", -"buffed", -"buffer", -"buffet", -"buffing", -"buffle", -"buffont", -"buffoon", -"buffy", -"bufidin", -"bufo", -"bug", -"bugaboo", -"bugan", -"bugbane", -"bugbear", -"bugbite", -"bugdom", -"bugfish", -"bugger", -"buggery", -"buggy", -"bughead", -"bugle", -"bugled", -"bugler", -"buglet", -"bugloss", -"bugre", -"bugseed", -"bugweed", -"bugwort", -"buhl", -"buhr", -"build", -"builder", -"buildup", -"built", -"buirdly", -"buisson", -"buist", -"bukh", -"bukshi", -"bulak", -"bulb", -"bulbar", -"bulbed", -"bulbil", -"bulblet", -"bulbose", -"bulbous", -"bulbul", -"bulbule", -"bulby", -"bulchin", -"bulge", -"bulger", -"bulgy", -"bulimia", -"bulimic", -"bulimy", -"bulk", -"bulked", -"bulker", -"bulkily", -"bulkish", -"bulky", -"bull", -"bulla", -"bullace", -"bullan", -"bullary", -"bullate", -"bullbat", -"bulldog", -"buller", -"bullet", -"bullety", -"bulling", -"bullion", -"bullish", -"bullism", -"bullit", -"bullnut", -"bullock", -"bullous", -"bullule", -"bully", -"bulrush", -"bulse", -"bult", -"bulter", -"bultey", -"bultong", -"bultow", -"bulwand", -"bulwark", -"bum", -"bumbaze", -"bumbee", -"bumble", -"bumbler", -"bumbo", -"bumboat", -"bumicky", -"bummalo", -"bummed", -"bummer", -"bummie", -"bumming", -"bummler", -"bummock", -"bump", -"bumpee", -"bumper", -"bumpily", -"bumping", -"bumpkin", -"bumpy", -"bumtrap", -"bumwood", -"bun", -"buna", -"buncal", -"bunce", -"bunch", -"buncher", -"bunchy", -"bund", -"bunder", -"bundle", -"bundler", -"bundlet", -"bundook", -"bundy", -"bung", -"bungee", -"bungey", -"bungfu", -"bungle", -"bungler", -"bungo", -"bungy", -"bunion", -"bunk", -"bunker", -"bunkery", -"bunkie", -"bunko", -"bunkum", -"bunnell", -"bunny", -"bunt", -"buntal", -"bunted", -"bunter", -"bunting", -"bunton", -"bunty", -"bunya", -"bunyah", -"bunyip", -"buoy", -"buoyage", -"buoyant", -"bur", -"buran", -"burao", -"burbank", -"burbark", -"burble", -"burbler", -"burbly", -"burbot", -"burbush", -"burd", -"burden", -"burdie", -"burdock", -"burdon", -"bure", -"bureau", -"bureaux", -"burel", -"burele", -"buret", -"burette", -"burfish", -"burg", -"burgage", -"burgall", -"burgee", -"burgeon", -"burgess", -"burgh", -"burghal", -"burgher", -"burglar", -"burgle", -"burgoo", -"burgul", -"burgus", -"burhead", -"buri", -"burial", -"burian", -"buried", -"burier", -"burin", -"burion", -"buriti", -"burka", -"burke", -"burker", -"burl", -"burlap", -"burled", -"burler", -"burlet", -"burlily", -"burly", -"burmite", -"burn", -"burned", -"burner", -"burnet", -"burnie", -"burning", -"burnish", -"burnous", -"burnout", -"burnt", -"burnut", -"burny", -"buro", -"burp", -"burr", -"burrah", -"burred", -"burrel", -"burrer", -"burring", -"burrish", -"burrito", -"burro", -"burrow", -"burry", -"bursa", -"bursal", -"bursar", -"bursary", -"bursate", -"burse", -"burseed", -"burst", -"burster", -"burt", -"burton", -"burucha", -"burweed", -"bury", -"burying", -"bus", -"busby", -"buscarl", -"bush", -"bushed", -"bushel", -"busher", -"bushful", -"bushi", -"bushily", -"bushing", -"bushlet", -"bushwa", -"bushy", -"busied", -"busily", -"busine", -"busk", -"busked", -"busker", -"busket", -"buskin", -"buskle", -"busky", -"busman", -"buss", -"busser", -"bussock", -"bussu", -"bust", -"bustard", -"busted", -"bustee", -"buster", -"bustic", -"bustle", -"bustled", -"bustler", -"busy", -"busying", -"busyish", -"but", -"butanal", -"butane", -"butanol", -"butch", -"butcher", -"butein", -"butene", -"butenyl", -"butic", -"butine", -"butler", -"butlery", -"butment", -"butoxy", -"butoxyl", -"butt", -"butte", -"butter", -"buttery", -"butting", -"buttle", -"buttock", -"button", -"buttons", -"buttony", -"butty", -"butyl", -"butylic", -"butyne", -"butyr", -"butyral", -"butyric", -"butyrin", -"butyryl", -"buxerry", -"buxom", -"buxomly", -"buy", -"buyable", -"buyer", -"buzane", -"buzz", -"buzzard", -"buzzer", -"buzzies", -"buzzing", -"buzzle", -"buzzwig", -"buzzy", -"by", -"bycoket", -"bye", -"byee", -"byeman", -"byepath", -"byerite", -"bygane", -"bygo", -"bygoing", -"bygone", -"byhand", -"bylaw", -"byname", -"byon", -"byous", -"byously", -"bypass", -"bypast", -"bypath", -"byplay", -"byre", -"byreman", -"byrlaw", -"byrnie", -"byroad", -"byrrus", -"bysen", -"byspell", -"byssal", -"byssin", -"byssine", -"byssoid", -"byssus", -"byth", -"bytime", -"bywalk", -"byway", -"bywoner", -"byword", -"bywork", -"c", -"ca", -"caam", -"caama", -"caaming", -"caapeba", -"cab", -"caba", -"cabaan", -"caback", -"cabaho", -"cabal", -"cabala", -"cabalic", -"caban", -"cabana", -"cabaret", -"cabas", -"cabbage", -"cabbagy", -"cabber", -"cabble", -"cabbler", -"cabby", -"cabda", -"caber", -"cabezon", -"cabin", -"cabinet", -"cabio", -"cable", -"cabled", -"cabler", -"cablet", -"cabling", -"cabman", -"cabob", -"cabocle", -"cabook", -"caboose", -"cabot", -"cabree", -"cabrit", -"cabuya", -"cacam", -"cacao", -"cachaza", -"cache", -"cachet", -"cachexy", -"cachou", -"cachrys", -"cacique", -"cack", -"cackle", -"cackler", -"cacodyl", -"cacoepy", -"caconym", -"cacoon", -"cacti", -"cactoid", -"cacur", -"cad", -"cadamba", -"cadaver", -"cadbait", -"cadbit", -"cadbote", -"caddice", -"caddie", -"caddis", -"caddish", -"caddle", -"caddow", -"caddy", -"cade", -"cadelle", -"cadence", -"cadency", -"cadent", -"cadenza", -"cader", -"caderas", -"cadet", -"cadetcy", -"cadette", -"cadew", -"cadge", -"cadger", -"cadgily", -"cadgy", -"cadi", -"cadism", -"cadjan", -"cadlock", -"cadmia", -"cadmic", -"cadmide", -"cadmium", -"cados", -"cadrans", -"cadre", -"cadua", -"caduac", -"caduca", -"cadus", -"cadweed", -"caeca", -"caecal", -"caecum", -"caeoma", -"caesura", -"cafeneh", -"cafenet", -"caffa", -"caffeic", -"caffeol", -"caffiso", -"caffle", -"caffoy", -"cafh", -"cafiz", -"caftan", -"cag", -"cage", -"caged", -"cageful", -"cageman", -"cager", -"cagey", -"caggy", -"cagily", -"cagit", -"cagmag", -"cahiz", -"cahoot", -"cahot", -"cahow", -"caickle", -"caid", -"caiman", -"caimito", -"cain", -"caique", -"caird", -"cairn", -"cairned", -"cairny", -"caisson", -"caitiff", -"cajeput", -"cajole", -"cajoler", -"cajuela", -"cajun", -"cajuput", -"cake", -"cakebox", -"caker", -"cakette", -"cakey", -"caky", -"cal", -"calaba", -"calaber", -"calade", -"calais", -"calalu", -"calamus", -"calash", -"calcar", -"calced", -"calcic", -"calcify", -"calcine", -"calcite", -"calcium", -"calculi", -"calden", -"caldron", -"calean", -"calends", -"calepin", -"calf", -"calfish", -"caliber", -"calibre", -"calices", -"calicle", -"calico", -"calid", -"caliga", -"caligo", -"calinda", -"calinut", -"calipee", -"caliper", -"caliph", -"caliver", -"calix", -"calk", -"calkage", -"calker", -"calkin", -"calking", -"call", -"callant", -"callboy", -"caller", -"callet", -"calli", -"callid", -"calling", -"callo", -"callose", -"callous", -"callow", -"callus", -"calm", -"calmant", -"calmer", -"calmly", -"calmy", -"calomba", -"calomel", -"calool", -"calor", -"caloric", -"calorie", -"caloris", -"calotte", -"caloyer", -"calp", -"calpac", -"calpack", -"caltrap", -"caltrop", -"calumba", -"calumet", -"calumny", -"calve", -"calved", -"calver", -"calves", -"calvish", -"calvity", -"calvous", -"calx", -"calyces", -"calycle", -"calymma", -"calypso", -"calyx", -"cam", -"camaca", -"camagon", -"camail", -"caman", -"camansi", -"camara", -"camass", -"camata", -"camb", -"cambaye", -"camber", -"cambial", -"cambism", -"cambist", -"cambium", -"cambrel", -"cambuca", -"came", -"cameist", -"camel", -"camelry", -"cameo", -"camera", -"cameral", -"camilla", -"camion", -"camise", -"camisia", -"camlet", -"cammed", -"cammock", -"camoodi", -"camp", -"campana", -"campane", -"camper", -"campho", -"camphol", -"camphor", -"campion", -"cample", -"campo", -"campody", -"campoo", -"campus", -"camus", -"camused", -"camwood", -"can", -"canaba", -"canada", -"canadol", -"canal", -"canamo", -"canape", -"canard", -"canari", -"canarin", -"canary", -"canasta", -"canaut", -"cancan", -"cancel", -"cancer", -"canch", -"cancrum", -"cand", -"candela", -"candent", -"candid", -"candied", -"candier", -"candify", -"candiru", -"candle", -"candler", -"candock", -"candor", -"candroy", -"candy", -"candys", -"cane", -"canel", -"canella", -"canelo", -"caner", -"canette", -"canful", -"cangan", -"cangia", -"cangle", -"cangler", -"cangue", -"canhoop", -"canid", -"canille", -"caninal", -"canine", -"caninus", -"canions", -"canjac", -"cank", -"canker", -"cankery", -"canman", -"canna", -"cannach", -"canned", -"cannel", -"canner", -"cannery", -"cannet", -"cannily", -"canning", -"cannon", -"cannot", -"cannula", -"canny", -"canoe", -"canon", -"canonic", -"canonry", -"canopic", -"canopy", -"canroy", -"canso", -"cant", -"cantala", -"cantar", -"cantara", -"cantaro", -"cantata", -"canted", -"canteen", -"canter", -"canthal", -"canthus", -"cantic", -"cantico", -"cantily", -"cantina", -"canting", -"cantion", -"cantish", -"cantle", -"cantlet", -"canto", -"canton", -"cantoon", -"cantor", -"cantred", -"cantref", -"cantrip", -"cantus", -"canty", -"canun", -"canvas", -"canvass", -"cany", -"canyon", -"canzon", -"caoba", -"cap", -"capable", -"capably", -"capanna", -"capanne", -"capax", -"capcase", -"cape", -"caped", -"capel", -"capelet", -"capelin", -"caper", -"caperer", -"capes", -"capful", -"caph", -"caphar", -"caphite", -"capias", -"capicha", -"capital", -"capitan", -"capivi", -"capkin", -"capless", -"caplin", -"capman", -"capmint", -"capomo", -"capon", -"caporal", -"capot", -"capote", -"capped", -"capper", -"cappie", -"capping", -"capple", -"cappy", -"caprate", -"capreol", -"capric", -"caprice", -"caprid", -"caprin", -"caprine", -"caproic", -"caproin", -"caprone", -"caproyl", -"capryl", -"capsa", -"capsid", -"capsize", -"capstan", -"capsula", -"capsule", -"captain", -"caption", -"captive", -"captor", -"capture", -"capuche", -"capulet", -"capulin", -"car", -"carabao", -"carabid", -"carabin", -"carabus", -"caracal", -"caracol", -"caract", -"carafe", -"caraibe", -"caraipi", -"caramba", -"caramel", -"caranda", -"carane", -"caranna", -"carapax", -"carapo", -"carat", -"caratch", -"caravan", -"caravel", -"caraway", -"carbarn", -"carbeen", -"carbene", -"carbide", -"carbine", -"carbo", -"carbon", -"carbona", -"carbora", -"carboxy", -"carboy", -"carbro", -"carbure", -"carbyl", -"carcake", -"carcass", -"carceag", -"carcel", -"carcoon", -"card", -"cardecu", -"carded", -"cardel", -"carder", -"cardia", -"cardiac", -"cardial", -"cardin", -"carding", -"cardo", -"cardol", -"cardon", -"cardona", -"cardoon", -"care", -"careen", -"career", -"careful", -"carene", -"carer", -"caress", -"carest", -"caret", -"carfare", -"carfax", -"carful", -"carga", -"cargo", -"carhop", -"cariama", -"caribou", -"carid", -"caries", -"carina", -"carinal", -"cariole", -"carious", -"cark", -"carking", -"carkled", -"carl", -"carless", -"carlet", -"carlie", -"carlin", -"carline", -"carling", -"carlish", -"carload", -"carlot", -"carls", -"carman", -"carmele", -"carmine", -"carmot", -"carnage", -"carnal", -"carnate", -"carneol", -"carney", -"carnic", -"carnify", -"carnose", -"carnous", -"caroa", -"carob", -"caroba", -"caroche", -"carol", -"caroler", -"caroli", -"carolin", -"carolus", -"carom", -"carone", -"caronic", -"caroome", -"caroon", -"carotic", -"carotid", -"carotin", -"carouse", -"carp", -"carpal", -"carpale", -"carpel", -"carpent", -"carper", -"carpet", -"carpid", -"carping", -"carpium", -"carport", -"carpos", -"carpus", -"carr", -"carrack", -"carrel", -"carrick", -"carried", -"carrier", -"carrion", -"carrizo", -"carroch", -"carrot", -"carroty", -"carrow", -"carry", -"carse", -"carshop", -"carsick", -"cart", -"cartage", -"carte", -"cartel", -"carter", -"cartful", -"cartman", -"carton", -"cartoon", -"cartway", -"carty", -"carua", -"carucal", -"carval", -"carve", -"carvel", -"carven", -"carvene", -"carver", -"carving", -"carvol", -"carvone", -"carvyl", -"caryl", -"casaba", -"casabe", -"casal", -"casalty", -"casate", -"casaun", -"casava", -"casave", -"casavi", -"casbah", -"cascade", -"cascado", -"cascara", -"casco", -"cascol", -"case", -"casease", -"caseate", -"casebox", -"cased", -"caseful", -"casefy", -"caseic", -"casein", -"caseose", -"caseous", -"caser", -"casern", -"caseum", -"cash", -"casha", -"cashaw", -"cashbox", -"cashboy", -"cashel", -"cashew", -"cashier", -"casing", -"casino", -"casiri", -"cask", -"casket", -"casking", -"casque", -"casqued", -"casquet", -"cass", -"cassady", -"casse", -"cassena", -"cassia", -"cassie", -"cassina", -"cassine", -"cassino", -"cassis", -"cassock", -"casson", -"cassoon", -"cast", -"caste", -"caster", -"castice", -"casting", -"castle", -"castled", -"castlet", -"castock", -"castoff", -"castor", -"castory", -"castra", -"castral", -"castrum", -"castuli", -"casual", -"casuary", -"casuist", -"casula", -"cat", -"catalpa", -"catan", -"catapan", -"cataria", -"catarrh", -"catasta", -"catbird", -"catboat", -"catcall", -"catch", -"catcher", -"catchup", -"catchy", -"catclaw", -"catdom", -"cate", -"catechu", -"catella", -"catena", -"catenae", -"cater", -"cateran", -"caterer", -"caterva", -"cateye", -"catface", -"catfall", -"catfish", -"catfoot", -"catgut", -"cathead", -"cathect", -"catheti", -"cathin", -"cathine", -"cathion", -"cathode", -"cathole", -"cathood", -"cathop", -"cathro", -"cation", -"cativo", -"catjang", -"catkin", -"catlap", -"catlike", -"catlin", -"catling", -"catmint", -"catnip", -"catpipe", -"catskin", -"catstep", -"catsup", -"cattabu", -"cattail", -"cattalo", -"cattery", -"cattily", -"catting", -"cattish", -"cattle", -"catty", -"catvine", -"catwalk", -"catwise", -"catwood", -"catwort", -"caubeen", -"cauboge", -"cauch", -"caucho", -"caucus", -"cauda", -"caudad", -"caudae", -"caudal", -"caudata", -"caudate", -"caudex", -"caudle", -"caught", -"cauk", -"caul", -"cauld", -"caules", -"cauline", -"caulis", -"caulome", -"caulote", -"caum", -"cauma", -"caunch", -"caup", -"caupo", -"caurale", -"causal", -"causate", -"cause", -"causer", -"causey", -"causing", -"causse", -"causson", -"caustic", -"cautel", -"cauter", -"cautery", -"caution", -"cautivo", -"cava", -"cavae", -"caval", -"cavalla", -"cavalry", -"cavate", -"cave", -"caveat", -"cavel", -"cavelet", -"cavern", -"cavetto", -"caviar", -"cavie", -"cavil", -"caviler", -"caving", -"cavings", -"cavish", -"cavity", -"caviya", -"cavort", -"cavus", -"cavy", -"caw", -"cawk", -"cawky", -"cawney", -"cawquaw", -"caxiri", -"caxon", -"cay", -"cayenne", -"cayman", -"caza", -"cazimi", -"ce", -"cearin", -"cease", -"ceasmic", -"cebell", -"cebian", -"cebid", -"cebil", -"cebine", -"ceboid", -"cebur", -"cecils", -"cecity", -"cedar", -"cedared", -"cedarn", -"cedary", -"cede", -"cedent", -"ceder", -"cedilla", -"cedrat", -"cedrate", -"cedre", -"cedrene", -"cedrin", -"cedrine", -"cedrium", -"cedrol", -"cedron", -"cedry", -"cedula", -"cee", -"ceibo", -"ceil", -"ceile", -"ceiler", -"ceilidh", -"ceiling", -"celadon", -"celemin", -"celery", -"celesta", -"celeste", -"celiac", -"celite", -"cell", -"cella", -"cellae", -"cellar", -"celled", -"cellist", -"cello", -"celloid", -"cellose", -"cellule", -"celsian", -"celt", -"celtium", -"celtuce", -"cembalo", -"cement", -"cenacle", -"cendre", -"cenoby", -"cense", -"censer", -"censive", -"censor", -"censual", -"censure", -"census", -"cent", -"centage", -"cental", -"centare", -"centaur", -"centavo", -"centena", -"center", -"centiar", -"centile", -"centime", -"centimo", -"centner", -"cento", -"centrad", -"central", -"centric", -"centrum", -"centry", -"centum", -"century", -"ceorl", -"cep", -"cepa", -"cepe", -"cephid", -"ceps", -"ceptor", -"cequi", -"cerago", -"ceral", -"ceramal", -"ceramic", -"ceras", -"cerasin", -"cerata", -"cerate", -"cerated", -"cercal", -"cerci", -"cercus", -"cere", -"cereal", -"cerebra", -"cered", -"cereous", -"cerer", -"ceresin", -"cerevis", -"ceria", -"ceric", -"ceride", -"cerillo", -"ceriman", -"cerin", -"cerine", -"ceriops", -"cerise", -"cerite", -"cerium", -"cermet", -"cern", -"cero", -"ceroma", -"cerote", -"cerotic", -"cerotin", -"cerous", -"cerrero", -"cerrial", -"cerris", -"certain", -"certie", -"certify", -"certis", -"certy", -"cerule", -"cerumen", -"ceruse", -"cervid", -"cervine", -"cervix", -"cervoid", -"ceryl", -"cesious", -"cesium", -"cess", -"cesser", -"cession", -"cessor", -"cesspit", -"cest", -"cestode", -"cestoid", -"cestrum", -"cestus", -"cetane", -"cetene", -"ceti", -"cetic", -"cetin", -"cetyl", -"cetylic", -"cevine", -"cha", -"chaa", -"chab", -"chabot", -"chabouk", -"chabuk", -"chacate", -"chack", -"chacker", -"chackle", -"chacma", -"chacona", -"chacte", -"chad", -"chaeta", -"chafe", -"chafer", -"chafery", -"chaff", -"chaffer", -"chaffy", -"chaft", -"chafted", -"chagan", -"chagrin", -"chaguar", -"chagul", -"chahar", -"chai", -"chain", -"chained", -"chainer", -"chainon", -"chair", -"chairer", -"chais", -"chaise", -"chaitya", -"chaja", -"chaka", -"chakar", -"chakari", -"chakazi", -"chakdar", -"chakobu", -"chakra", -"chakram", -"chaksi", -"chal", -"chalaco", -"chalana", -"chalaza", -"chalaze", -"chalcid", -"chalcon", -"chalcus", -"chalder", -"chalet", -"chalice", -"chalk", -"chalker", -"chalky", -"challah", -"challie", -"challis", -"chalmer", -"chalon", -"chalone", -"chalque", -"chalta", -"chalutz", -"cham", -"chamal", -"chamar", -"chamber", -"chambul", -"chamfer", -"chamiso", -"chamite", -"chamma", -"chamois", -"champ", -"champac", -"champer", -"champy", -"chance", -"chancel", -"chancer", -"chanche", -"chanco", -"chancre", -"chancy", -"chandam", -"chandi", -"chandoo", -"chandu", -"chandul", -"chang", -"changa", -"changar", -"change", -"changer", -"chank", -"channel", -"channer", -"chanson", -"chanst", -"chant", -"chanter", -"chantey", -"chantry", -"chao", -"chaos", -"chaotic", -"chap", -"chapah", -"chape", -"chapeau", -"chaped", -"chapel", -"chapin", -"chaplet", -"chapman", -"chapped", -"chapper", -"chappie", -"chappin", -"chappow", -"chappy", -"chaps", -"chapt", -"chapter", -"char", -"charac", -"charade", -"charas", -"charbon", -"chard", -"chare", -"charer", -"charet", -"charge", -"chargee", -"charger", -"charier", -"charily", -"chariot", -"charism", -"charity", -"chark", -"charka", -"charkha", -"charm", -"charmel", -"charmer", -"charnel", -"charpit", -"charpoy", -"charqui", -"charr", -"charry", -"chart", -"charter", -"charuk", -"chary", -"chase", -"chaser", -"chasing", -"chasm", -"chasma", -"chasmal", -"chasmed", -"chasmic", -"chasmy", -"chasse", -"chassis", -"chaste", -"chasten", -"chat", -"chataka", -"chateau", -"chati", -"chatta", -"chattel", -"chatter", -"chatty", -"chauk", -"chaus", -"chaute", -"chauth", -"chavish", -"chaw", -"chawan", -"chawer", -"chawk", -"chawl", -"chay", -"chaya", -"chayote", -"chazan", -"che", -"cheap", -"cheapen", -"cheaply", -"cheat", -"cheatee", -"cheater", -"chebec", -"chebel", -"chebog", -"chebule", -"check", -"checked", -"checker", -"checkup", -"checky", -"cheder", -"chee", -"cheecha", -"cheek", -"cheeker", -"cheeky", -"cheep", -"cheeper", -"cheepy", -"cheer", -"cheered", -"cheerer", -"cheerio", -"cheerly", -"cheery", -"cheese", -"cheeser", -"cheesy", -"cheet", -"cheetah", -"cheeter", -"cheetie", -"chef", -"chegoe", -"chegre", -"cheir", -"chekan", -"cheke", -"cheki", -"chekmak", -"chela", -"chelate", -"chelem", -"chelide", -"chello", -"chelone", -"chelp", -"chelys", -"chemic", -"chemis", -"chemise", -"chemism", -"chemist", -"chena", -"chende", -"cheng", -"chenica", -"cheque", -"cherem", -"cherish", -"cheroot", -"cherry", -"chert", -"cherte", -"cherty", -"cherub", -"chervil", -"cheson", -"chess", -"chessel", -"chesser", -"chest", -"chester", -"chesty", -"cheth", -"chettik", -"chetty", -"chevage", -"cheval", -"cheve", -"cheven", -"chevin", -"chevise", -"chevon", -"chevron", -"chevy", -"chew", -"chewer", -"chewink", -"chewy", -"cheyney", -"chhatri", -"chi", -"chia", -"chiasm", -"chiasma", -"chiaus", -"chibouk", -"chibrit", -"chic", -"chicane", -"chichi", -"chick", -"chicken", -"chicker", -"chicky", -"chicle", -"chico", -"chicory", -"chicot", -"chicote", -"chid", -"chidden", -"chide", -"chider", -"chiding", -"chidra", -"chief", -"chiefly", -"chield", -"chien", -"chiffer", -"chiffon", -"chiggak", -"chigger", -"chignon", -"chigoe", -"chih", -"chihfu", -"chikara", -"chil", -"child", -"childe", -"childed", -"childly", -"chile", -"chili", -"chiliad", -"chill", -"chilla", -"chilled", -"chiller", -"chillo", -"chillum", -"chilly", -"chiloma", -"chilver", -"chimble", -"chime", -"chimer", -"chimera", -"chimney", -"chin", -"china", -"chinar", -"chinch", -"chincha", -"chinche", -"chine", -"chined", -"ching", -"chingma", -"chinik", -"chinin", -"chink", -"chinker", -"chinkle", -"chinks", -"chinky", -"chinnam", -"chinned", -"chinny", -"chino", -"chinoa", -"chinol", -"chinse", -"chint", -"chintz", -"chip", -"chiplet", -"chipped", -"chipper", -"chippy", -"chips", -"chiral", -"chirata", -"chiripa", -"chirk", -"chirm", -"chiro", -"chirp", -"chirper", -"chirpy", -"chirr", -"chirrup", -"chisel", -"chit", -"chitak", -"chital", -"chitin", -"chiton", -"chitose", -"chitra", -"chitter", -"chitty", -"chive", -"chivey", -"chkalik", -"chlamyd", -"chlamys", -"chlor", -"chloral", -"chlore", -"chloric", -"chloryl", -"cho", -"choana", -"choate", -"choaty", -"chob", -"choca", -"chocard", -"chocho", -"chock", -"chocker", -"choel", -"choenix", -"choffer", -"choga", -"chogak", -"chogset", -"choice", -"choicy", -"choil", -"choiler", -"choir", -"chokage", -"choke", -"choker", -"choking", -"chokra", -"choky", -"chol", -"chola", -"cholane", -"cholate", -"chold", -"choleic", -"choler", -"cholera", -"choli", -"cholic", -"choline", -"cholla", -"choller", -"cholum", -"chomp", -"chondre", -"chonta", -"choop", -"choose", -"chooser", -"choosy", -"chop", -"chopa", -"chopin", -"chopine", -"chopped", -"chopper", -"choppy", -"choragy", -"choral", -"chord", -"chorda", -"chordal", -"chorded", -"chore", -"chorea", -"choreal", -"choree", -"choregy", -"choreic", -"choreus", -"chorial", -"choric", -"chorine", -"chorion", -"chorism", -"chorist", -"chorogi", -"choroid", -"chorook", -"chort", -"chorten", -"chortle", -"chorus", -"choryos", -"chose", -"chosen", -"chott", -"chough", -"chouka", -"choup", -"chous", -"chouse", -"chouser", -"chow", -"chowder", -"chowk", -"chowry", -"choya", -"chria", -"chrism", -"chrisma", -"chrisom", -"chroma", -"chrome", -"chromic", -"chromid", -"chromo", -"chromy", -"chromyl", -"chronal", -"chronic", -"chrotta", -"chrysal", -"chrysid", -"chrysin", -"chub", -"chubbed", -"chubby", -"chuck", -"chucker", -"chuckle", -"chucky", -"chuddar", -"chufa", -"chuff", -"chuffy", -"chug", -"chugger", -"chuhra", -"chukar", -"chukker", -"chukor", -"chulan", -"chullpa", -"chum", -"chummer", -"chummy", -"chump", -"chumpy", -"chun", -"chunari", -"chunga", -"chunk", -"chunky", -"chunner", -"chunnia", -"chunter", -"chupak", -"chupon", -"church", -"churchy", -"churel", -"churl", -"churled", -"churly", -"churm", -"churn", -"churr", -"churrus", -"chut", -"chute", -"chuter", -"chutney", -"chyack", -"chyak", -"chyle", -"chylify", -"chyloid", -"chylous", -"chymase", -"chyme", -"chymia", -"chymic", -"chymify", -"chymous", -"chypre", -"chytra", -"chytrid", -"cibol", -"cibory", -"ciboule", -"cicad", -"cicada", -"cicadid", -"cicala", -"cicely", -"cicer", -"cichlid", -"cidarid", -"cidaris", -"cider", -"cig", -"cigala", -"cigar", -"cigua", -"cilia", -"ciliary", -"ciliate", -"cilice", -"cilium", -"cimbia", -"cimelia", -"cimex", -"cimicid", -"cimline", -"cinch", -"cincher", -"cinclis", -"cinct", -"cinder", -"cindery", -"cine", -"cinel", -"cinema", -"cinene", -"cineole", -"cinerea", -"cingle", -"cinnyl", -"cinque", -"cinter", -"cinuran", -"cion", -"cipher", -"cipo", -"cipolin", -"cippus", -"circa", -"circle", -"circled", -"circler", -"circlet", -"circuit", -"circus", -"circusy", -"cirque", -"cirrate", -"cirri", -"cirrose", -"cirrous", -"cirrus", -"cirsoid", -"ciruela", -"cisco", -"cise", -"cisele", -"cissing", -"cissoid", -"cist", -"cista", -"cistae", -"cisted", -"cistern", -"cistic", -"cit", -"citable", -"citadel", -"citator", -"cite", -"citee", -"citer", -"citess", -"cithara", -"cither", -"citied", -"citify", -"citizen", -"citole", -"citral", -"citrate", -"citrean", -"citrene", -"citric", -"citril", -"citrin", -"citrine", -"citron", -"citrous", -"citrus", -"cittern", -"citua", -"city", -"citydom", -"cityful", -"cityish", -"cive", -"civet", -"civic", -"civics", -"civil", -"civilly", -"civism", -"civvy", -"cixiid", -"clabber", -"clachan", -"clack", -"clacker", -"clacket", -"clad", -"cladine", -"cladode", -"cladose", -"cladus", -"clag", -"claggum", -"claggy", -"claim", -"claimer", -"clairce", -"claith", -"claiver", -"clam", -"clamant", -"clamb", -"clamber", -"clame", -"clamer", -"clammed", -"clammer", -"clammy", -"clamor", -"clamp", -"clamper", -"clan", -"clang", -"clangor", -"clank", -"clanned", -"clap", -"clapnet", -"clapped", -"clapper", -"clapt", -"claque", -"claquer", -"clarain", -"claret", -"clarify", -"clarin", -"clarion", -"clarity", -"clark", -"claro", -"clart", -"clarty", -"clary", -"clash", -"clasher", -"clashy", -"clasp", -"clasper", -"claspt", -"class", -"classed", -"classer", -"classes", -"classic", -"classis", -"classy", -"clastic", -"clat", -"clatch", -"clatter", -"clatty", -"claught", -"clausal", -"clause", -"claut", -"clava", -"claval", -"clavate", -"clave", -"clavel", -"claver", -"clavial", -"clavier", -"claviol", -"clavis", -"clavola", -"clavus", -"clavy", -"claw", -"clawed", -"clawer", -"clawk", -"clawker", -"clay", -"clayen", -"clayer", -"clayey", -"clayish", -"clayman", -"claypan", -"cleach", -"clead", -"cleaded", -"cleam", -"cleamer", -"clean", -"cleaner", -"cleanly", -"cleanse", -"cleanup", -"clear", -"clearer", -"clearly", -"cleat", -"cleave", -"cleaver", -"cleche", -"cleck", -"cled", -"cledge", -"cledgy", -"clee", -"cleek", -"cleeked", -"cleeky", -"clef", -"cleft", -"clefted", -"cleg", -"clem", -"clement", -"clench", -"cleoid", -"clep", -"clergy", -"cleric", -"clerid", -"clerisy", -"clerk", -"clerkly", -"cleruch", -"cletch", -"cleuch", -"cleve", -"clever", -"clevis", -"clew", -"cliack", -"cliche", -"click", -"clicker", -"clicket", -"clicky", -"cliency", -"client", -"cliff", -"cliffed", -"cliffy", -"clift", -"clifty", -"clima", -"climata", -"climate", -"climath", -"climax", -"climb", -"climber", -"clime", -"clinal", -"clinch", -"cline", -"cling", -"clinger", -"clingy", -"clinia", -"clinic", -"clinium", -"clink", -"clinker", -"clinkum", -"clinoid", -"clint", -"clinty", -"clip", -"clipei", -"clipeus", -"clipped", -"clipper", -"clips", -"clipse", -"clipt", -"clique", -"cliquy", -"clisere", -"clit", -"clitch", -"clite", -"clites", -"clithe", -"clitia", -"clition", -"clitter", -"clival", -"clive", -"clivers", -"clivis", -"clivus", -"cloaca", -"cloacal", -"cloak", -"cloaked", -"cloam", -"cloamen", -"cloamer", -"clobber", -"clochan", -"cloche", -"clocher", -"clock", -"clocked", -"clocker", -"clod", -"clodder", -"cloddy", -"clodlet", -"cloff", -"clog", -"clogger", -"cloggy", -"cloghad", -"clogwyn", -"cloit", -"clomb", -"clomben", -"clonal", -"clone", -"clonic", -"clonism", -"clonus", -"cloof", -"cloop", -"cloot", -"clootie", -"clop", -"close", -"closed", -"closely", -"closen", -"closer", -"closet", -"closh", -"closish", -"closter", -"closure", -"clot", -"clotbur", -"clote", -"cloth", -"clothe", -"clothes", -"clothy", -"clotter", -"clotty", -"cloture", -"cloud", -"clouded", -"cloudy", -"clough", -"clour", -"clout", -"clouted", -"clouter", -"clouty", -"clove", -"cloven", -"clovene", -"clover", -"clovery", -"clow", -"clown", -"cloy", -"cloyer", -"cloying", -"club", -"clubbed", -"clubber", -"clubby", -"clubdom", -"clubman", -"cluck", -"clue", -"cluff", -"clump", -"clumpy", -"clumse", -"clumsy", -"clunch", -"clung", -"clunk", -"clupeid", -"cluster", -"clutch", -"cluther", -"clutter", -"cly", -"clyer", -"clype", -"clypeal", -"clypeus", -"clysis", -"clysma", -"clysmic", -"clyster", -"cnemial", -"cnemis", -"cnicin", -"cnida", -"coabode", -"coach", -"coachee", -"coacher", -"coachy", -"coact", -"coactor", -"coadapt", -"coadmit", -"coadore", -"coaged", -"coagent", -"coagula", -"coaid", -"coaita", -"coak", -"coakum", -"coal", -"coalbag", -"coalbin", -"coalbox", -"coaler", -"coalify", -"coalize", -"coalpit", -"coaly", -"coaming", -"coannex", -"coapt", -"coarb", -"coarse", -"coarsen", -"coast", -"coastal", -"coaster", -"coat", -"coated", -"coatee", -"coater", -"coati", -"coatie", -"coating", -"coax", -"coaxal", -"coaxer", -"coaxial", -"coaxing", -"coaxy", -"cob", -"cobaea", -"cobalt", -"cobang", -"cobbed", -"cobber", -"cobbing", -"cobble", -"cobbler", -"cobbly", -"cobbra", -"cobby", -"cobcab", -"cobego", -"cobhead", -"cobia", -"cobiron", -"coble", -"cobless", -"cobloaf", -"cobnut", -"cobola", -"cobourg", -"cobra", -"coburg", -"cobweb", -"cobwork", -"coca", -"cocaine", -"cocash", -"cocause", -"coccal", -"cocci", -"coccid", -"cocco", -"coccoid", -"coccous", -"coccule", -"coccus", -"coccyx", -"cochal", -"cochief", -"cochlea", -"cock", -"cockade", -"cockal", -"cocked", -"cocker", -"cocket", -"cockeye", -"cockily", -"cocking", -"cockish", -"cockle", -"cockled", -"cockler", -"cocklet", -"cockly", -"cockney", -"cockpit", -"cockshy", -"cockup", -"cocky", -"coco", -"cocoa", -"cocoach", -"coconut", -"cocoon", -"cocotte", -"coctile", -"coction", -"cocuisa", -"cocullo", -"cocuyo", -"cod", -"coda", -"codbank", -"codder", -"codding", -"coddle", -"coddler", -"code", -"codeine", -"coder", -"codex", -"codfish", -"codger", -"codhead", -"codical", -"codices", -"codicil", -"codify", -"codilla", -"codille", -"codist", -"codling", -"codman", -"codo", -"codol", -"codon", -"codworm", -"coe", -"coecal", -"coecum", -"coed", -"coelar", -"coelder", -"coelect", -"coelho", -"coelia", -"coeliac", -"coelian", -"coelin", -"coeline", -"coelom", -"coeloma", -"coempt", -"coenact", -"coenjoy", -"coenobe", -"coequal", -"coerce", -"coercer", -"coetus", -"coeval", -"coexert", -"coexist", -"coff", -"coffee", -"coffer", -"coffin", -"coffle", -"coffret", -"coft", -"cog", -"cogence", -"cogency", -"cogener", -"cogent", -"cogged", -"cogger", -"coggie", -"cogging", -"coggle", -"coggly", -"coghle", -"cogman", -"cognac", -"cognate", -"cognize", -"cogon", -"cogonal", -"cograil", -"cogroad", -"cogue", -"cogway", -"cogwood", -"cohabit", -"coheir", -"cohere", -"coherer", -"cohibit", -"coho", -"cohoba", -"cohol", -"cohort", -"cohosh", -"cohune", -"coif", -"coifed", -"coign", -"coigue", -"coil", -"coiled", -"coiler", -"coiling", -"coin", -"coinage", -"coiner", -"coinfer", -"coining", -"cointer", -"coiny", -"coir", -"coital", -"coition", -"coiture", -"coitus", -"cojudge", -"cojuror", -"coke", -"cokeman", -"coker", -"cokery", -"coking", -"coky", -"col", -"cola", -"colane", -"colarin", -"colate", -"colauxe", -"colback", -"cold", -"colder", -"coldish", -"coldly", -"cole", -"coletit", -"coleur", -"coli", -"colibri", -"colic", -"colical", -"colicky", -"colima", -"colin", -"coling", -"colitic", -"colitis", -"colk", -"coll", -"collage", -"collar", -"collard", -"collare", -"collate", -"collaud", -"collect", -"colleen", -"college", -"collery", -"collet", -"colley", -"collide", -"collie", -"collied", -"collier", -"collin", -"colline", -"colling", -"collins", -"collock", -"colloid", -"collop", -"collude", -"collum", -"colly", -"collyba", -"colmar", -"colobin", -"colon", -"colonel", -"colonic", -"colony", -"color", -"colored", -"colorer", -"colorin", -"colors", -"colory", -"coloss", -"colossi", -"colove", -"colp", -"colpeo", -"colport", -"colpus", -"colt", -"colter", -"coltish", -"colugo", -"columbo", -"column", -"colunar", -"colure", -"coly", -"colyone", -"colytic", -"colyum", -"colza", -"coma", -"comaker", -"comal", -"comamie", -"comanic", -"comart", -"comate", -"comb", -"combat", -"combed", -"comber", -"combine", -"combing", -"comble", -"comboy", -"combure", -"combust", -"comby", -"come", -"comedic", -"comedo", -"comedy", -"comely", -"comenic", -"comer", -"comes", -"comet", -"cometic", -"comfit", -"comfort", -"comfrey", -"comfy", -"comic", -"comical", -"comicry", -"coming", -"comino", -"comism", -"comital", -"comitia", -"comity", -"comma", -"command", -"commend", -"comment", -"commie", -"commit", -"commix", -"commixt", -"commode", -"common", -"commons", -"commot", -"commove", -"communa", -"commune", -"commute", -"comoid", -"comose", -"comourn", -"comous", -"compact", -"company", -"compare", -"compart", -"compass", -"compear", -"compeer", -"compel", -"compend", -"compete", -"compile", -"complex", -"complin", -"complot", -"comply", -"compo", -"compoer", -"compole", -"compone", -"compony", -"comport", -"compos", -"compose", -"compost", -"compote", -"compreg", -"compter", -"compute", -"comrade", -"con", -"conacre", -"conal", -"conamed", -"conatus", -"concave", -"conceal", -"concede", -"conceit", -"concent", -"concept", -"concern", -"concert", -"conch", -"concha", -"conchal", -"conche", -"conched", -"concher", -"conchy", -"concile", -"concise", -"concoct", -"concord", -"concupy", -"concur", -"concuss", -"cond", -"condemn", -"condign", -"condite", -"condole", -"condone", -"condor", -"conduce", -"conduct", -"conduit", -"condyle", -"cone", -"coned", -"coneen", -"coneine", -"conelet", -"coner", -"cones", -"confab", -"confact", -"confect", -"confess", -"confide", -"confine", -"confirm", -"confix", -"conflow", -"conflux", -"conform", -"confuse", -"confute", -"conga", -"congeal", -"congee", -"conger", -"congest", -"congius", -"congou", -"conic", -"conical", -"conicle", -"conics", -"conidia", -"conifer", -"conima", -"conin", -"conine", -"conject", -"conjoin", -"conjure", -"conjury", -"conk", -"conker", -"conkers", -"conky", -"conn", -"connach", -"connate", -"connect", -"conner", -"connex", -"conning", -"connive", -"connote", -"conoid", -"conopid", -"conquer", -"conred", -"consent", -"consign", -"consist", -"consol", -"console", -"consort", -"conspue", -"constat", -"consul", -"consult", -"consume", -"consute", -"contact", -"contain", -"conte", -"contect", -"contemn", -"content", -"conter", -"contest", -"context", -"contise", -"conto", -"contort", -"contour", -"contra", -"control", -"contund", -"contuse", -"conure", -"conus", -"conusee", -"conusor", -"conuzee", -"conuzor", -"convect", -"convene", -"convent", -"convert", -"conveth", -"convex", -"convey", -"convict", -"convive", -"convoke", -"convoy", -"cony", -"coo", -"cooba", -"coodle", -"cooee", -"cooer", -"coof", -"cooing", -"cooja", -"cook", -"cookdom", -"cookee", -"cooker", -"cookery", -"cooking", -"cookish", -"cookout", -"cooky", -"cool", -"coolant", -"coolen", -"cooler", -"coolie", -"cooling", -"coolish", -"coolly", -"coolth", -"coolung", -"cooly", -"coom", -"coomb", -"coomy", -"coon", -"cooncan", -"coonily", -"coontie", -"coony", -"coop", -"cooper", -"coopery", -"cooree", -"coorie", -"cooser", -"coost", -"coot", -"cooter", -"coothay", -"cootie", -"cop", -"copa", -"copable", -"copaene", -"copaiba", -"copaiye", -"copal", -"copalm", -"copart", -"coparty", -"cope", -"copei", -"copeman", -"copen", -"copepod", -"coper", -"coperta", -"copied", -"copier", -"copilot", -"coping", -"copious", -"copis", -"copist", -"copita", -"copolar", -"copped", -"copper", -"coppery", -"coppet", -"coppice", -"coppin", -"copping", -"copple", -"coppled", -"coppy", -"copr", -"copra", -"coprose", -"copse", -"copsing", -"copsy", -"copter", -"copula", -"copular", -"copus", -"copy", -"copycat", -"copyism", -"copyist", -"copyman", -"coque", -"coquet", -"coquina", -"coquita", -"coquito", -"cor", -"cora", -"corach", -"coracle", -"corah", -"coraise", -"coral", -"coraled", -"coram", -"coranto", -"corban", -"corbeau", -"corbeil", -"corbel", -"corbie", -"corbula", -"corcass", -"corcir", -"cord", -"cordage", -"cordant", -"cordate", -"cordax", -"corded", -"cordel", -"corder", -"cordial", -"cordies", -"cording", -"cordite", -"cordoba", -"cordon", -"cordy", -"cordyl", -"core", -"corebel", -"cored", -"coreid", -"coreign", -"corella", -"corer", -"corf", -"corge", -"corgi", -"corial", -"coriin", -"coring", -"corinne", -"corium", -"cork", -"corkage", -"corke", -"corked", -"corker", -"corking", -"corkish", -"corkite", -"corky", -"corm", -"cormel", -"cormoid", -"cormous", -"cormus", -"corn", -"cornage", -"cornbin", -"corncob", -"cornea", -"corneal", -"cornein", -"cornel", -"corner", -"cornet", -"corneum", -"cornic", -"cornice", -"cornin", -"corning", -"cornu", -"cornual", -"cornule", -"cornute", -"cornuto", -"corny", -"coroa", -"corody", -"corol", -"corolla", -"corona", -"coronad", -"coronae", -"coronal", -"coroner", -"coronet", -"corozo", -"corp", -"corpora", -"corps", -"corpse", -"corpus", -"corrade", -"corral", -"correal", -"correct", -"corrie", -"corrige", -"corrode", -"corrupt", -"corsac", -"corsage", -"corsair", -"corse", -"corset", -"corsie", -"corsite", -"corta", -"cortege", -"cortex", -"cortez", -"cortin", -"cortina", -"coruco", -"coruler", -"corupay", -"corver", -"corvina", -"corvine", -"corvoid", -"coryl", -"corylin", -"corymb", -"coryza", -"cos", -"cosaque", -"coscet", -"coseat", -"cosec", -"cosech", -"coseism", -"coset", -"cosh", -"cosher", -"coshery", -"cosily", -"cosine", -"cosmic", -"cosmism", -"cosmist", -"cosmos", -"coss", -"cossas", -"cosse", -"cosset", -"cossid", -"cost", -"costa", -"costal", -"costar", -"costard", -"costate", -"costean", -"coster", -"costing", -"costive", -"costly", -"costrel", -"costula", -"costume", -"cosy", -"cot", -"cotch", -"cote", -"coteful", -"coterie", -"coth", -"cothe", -"cothish", -"cothon", -"cothurn", -"cothy", -"cotidal", -"cotise", -"cotland", -"cotman", -"coto", -"cotoin", -"cotoro", -"cotrine", -"cotset", -"cotta", -"cottage", -"cotte", -"cotted", -"cotter", -"cottid", -"cottier", -"cottoid", -"cotton", -"cottony", -"cotty", -"cotuit", -"cotula", -"cotutor", -"cotwin", -"cotwist", -"cotyla", -"cotylar", -"cotype", -"couac", -"coucal", -"couch", -"couched", -"couchee", -"coucher", -"couchy", -"coude", -"coudee", -"coue", -"cougar", -"cough", -"cougher", -"cougnar", -"coul", -"could", -"coulee", -"coulomb", -"coulure", -"couma", -"coumara", -"council", -"counite", -"counsel", -"count", -"counter", -"countor", -"country", -"county", -"coup", -"coupage", -"coupe", -"couped", -"coupee", -"couper", -"couple", -"coupled", -"coupler", -"couplet", -"coupon", -"coupure", -"courage", -"courant", -"courap", -"courb", -"courge", -"courida", -"courier", -"couril", -"courlan", -"course", -"coursed", -"courser", -"court", -"courter", -"courtin", -"courtly", -"cousin", -"cousiny", -"coutel", -"couter", -"couth", -"couthie", -"coutil", -"couvade", -"couxia", -"covado", -"cove", -"coved", -"covent", -"cover", -"covered", -"coverer", -"covert", -"covet", -"coveter", -"covey", -"covid", -"covin", -"coving", -"covisit", -"covite", -"cow", -"cowal", -"coward", -"cowardy", -"cowbane", -"cowbell", -"cowbind", -"cowbird", -"cowboy", -"cowdie", -"coween", -"cower", -"cowfish", -"cowgate", -"cowgram", -"cowhage", -"cowheel", -"cowherb", -"cowherd", -"cowhide", -"cowhorn", -"cowish", -"cowitch", -"cowl", -"cowle", -"cowled", -"cowlick", -"cowlike", -"cowling", -"cowman", -"cowpath", -"cowpea", -"cowpen", -"cowpock", -"cowpox", -"cowrie", -"cowroid", -"cowshed", -"cowskin", -"cowslip", -"cowtail", -"cowweed", -"cowy", -"cowyard", -"cox", -"coxa", -"coxal", -"coxcomb", -"coxite", -"coxitis", -"coxy", -"coy", -"coyan", -"coydog", -"coyish", -"coyly", -"coyness", -"coynye", -"coyo", -"coyol", -"coyote", -"coypu", -"coyure", -"coz", -"coze", -"cozen", -"cozener", -"cozier", -"cozily", -"cozy", -"crab", -"crabbed", -"crabber", -"crabby", -"craber", -"crablet", -"crabman", -"crack", -"cracked", -"cracker", -"crackle", -"crackly", -"cracky", -"craddy", -"cradge", -"cradle", -"cradler", -"craft", -"crafty", -"crag", -"craggan", -"cragged", -"craggy", -"craichy", -"crain", -"craisey", -"craizey", -"crajuru", -"crake", -"crakow", -"cram", -"crambe", -"crambid", -"cramble", -"crambly", -"crambo", -"crammer", -"cramp", -"cramped", -"cramper", -"crampet", -"crampon", -"crampy", -"cran", -"cranage", -"crance", -"crane", -"craner", -"craney", -"crania", -"craniad", -"cranial", -"cranian", -"cranic", -"cranium", -"crank", -"cranked", -"cranker", -"crankle", -"crankly", -"crankum", -"cranky", -"crannog", -"cranny", -"crants", -"crap", -"crapaud", -"crape", -"crappie", -"crappin", -"crapple", -"crappo", -"craps", -"crapy", -"crare", -"crash", -"crasher", -"crasis", -"crass", -"crassly", -"cratch", -"crate", -"crater", -"craunch", -"cravat", -"crave", -"craven", -"craver", -"craving", -"cravo", -"craw", -"crawdad", -"crawful", -"crawl", -"crawler", -"crawley", -"crawly", -"crawm", -"crawtae", -"crayer", -"crayon", -"craze", -"crazed", -"crazily", -"crazy", -"crea", -"creagh", -"creaght", -"creak", -"creaker", -"creaky", -"cream", -"creamer", -"creamy", -"creance", -"creant", -"crease", -"creaser", -"creasy", -"creat", -"create", -"creatic", -"creator", -"creche", -"credent", -"credit", -"cree", -"creed", -"creedal", -"creeded", -"creek", -"creeker", -"creeky", -"creel", -"creeler", -"creem", -"creen", -"creep", -"creeper", -"creepie", -"creepy", -"creese", -"creesh", -"creeshy", -"cremate", -"cremone", -"cremor", -"cremule", -"crena", -"crenate", -"crenel", -"crenele", -"crenic", -"crenula", -"creole", -"creosol", -"crepe", -"crepine", -"crepon", -"crept", -"crepy", -"cresol", -"cresoxy", -"cress", -"cressed", -"cresset", -"cresson", -"cressy", -"crest", -"crested", -"cresyl", -"creta", -"cretic", -"cretify", -"cretin", -"cretion", -"crevice", -"crew", -"crewel", -"crewer", -"crewman", -"crib", -"cribber", -"cribble", -"cribo", -"cribral", -"cric", -"crick", -"cricket", -"crickey", -"crickle", -"cricoid", -"cried", -"crier", -"criey", -"crig", -"crile", -"crime", -"crimine", -"crimp", -"crimper", -"crimple", -"crimpy", -"crimson", -"crin", -"crinal", -"crine", -"crined", -"crinet", -"cringe", -"cringer", -"cringle", -"crinite", -"crink", -"crinkle", -"crinkly", -"crinoid", -"crinose", -"crinula", -"cripes", -"cripple", -"cripply", -"crises", -"crisic", -"crisis", -"crisp", -"crisped", -"crisper", -"crisply", -"crispy", -"criss", -"crissal", -"crissum", -"crista", -"critch", -"crith", -"critic", -"crizzle", -"cro", -"croak", -"croaker", -"croaky", -"croc", -"crocard", -"croceic", -"crocein", -"croche", -"crochet", -"croci", -"crocin", -"crock", -"crocker", -"crocket", -"crocky", -"crocus", -"croft", -"crofter", -"crome", -"crone", -"cronet", -"cronish", -"cronk", -"crony", -"crood", -"croodle", -"crook", -"crooked", -"crooken", -"crookle", -"crool", -"croon", -"crooner", -"crop", -"cropman", -"croppa", -"cropper", -"croppie", -"croppy", -"croquet", -"crore", -"crosa", -"crosier", -"crosnes", -"cross", -"crosse", -"crossed", -"crosser", -"crossly", -"crotal", -"crotalo", -"crotch", -"crotchy", -"crotin", -"crottle", -"crotyl", -"crouch", -"croup", -"croupal", -"croupe", -"croupy", -"crouse", -"crout", -"croute", -"crouton", -"crow", -"crowbar", -"crowd", -"crowded", -"crowder", -"crowdy", -"crower", -"crowhop", -"crowing", -"crowl", -"crown", -"crowned", -"crowner", -"crowtoe", -"croy", -"croyden", -"croydon", -"croze", -"crozer", -"crozzle", -"crozzly", -"crubeen", -"cruce", -"cruces", -"cruche", -"crucial", -"crucian", -"crucify", -"crucily", -"cruck", -"crude", -"crudely", -"crudity", -"cruel", -"cruelly", -"cruels", -"cruelty", -"cruent", -"cruet", -"cruety", -"cruise", -"cruiser", -"cruive", -"cruller", -"crum", -"crumb", -"crumber", -"crumble", -"crumbly", -"crumby", -"crumen", -"crumlet", -"crummie", -"crummy", -"crump", -"crumper", -"crumpet", -"crumple", -"crumply", -"crumpy", -"crunch", -"crunchy", -"crunk", -"crunkle", -"crunode", -"crunt", -"cruor", -"crupper", -"crural", -"crureus", -"crus", -"crusade", -"crusado", -"cruse", -"crush", -"crushed", -"crusher", -"crusie", -"crusily", -"crust", -"crusta", -"crustal", -"crusted", -"cruster", -"crusty", -"crutch", -"cruth", -"crutter", -"crux", -"cry", -"cryable", -"crybaby", -"crying", -"cryogen", -"cryosel", -"crypt", -"crypta", -"cryptal", -"crypted", -"cryptic", -"crystal", -"crystic", -"csardas", -"ctene", -"ctenoid", -"cuadra", -"cuarta", -"cub", -"cubage", -"cubbing", -"cubbish", -"cubby", -"cubdom", -"cube", -"cubeb", -"cubelet", -"cuber", -"cubhood", -"cubi", -"cubic", -"cubica", -"cubical", -"cubicle", -"cubicly", -"cubism", -"cubist", -"cubit", -"cubital", -"cubited", -"cubito", -"cubitus", -"cuboid", -"cuck", -"cuckold", -"cuckoo", -"cuculla", -"cud", -"cudava", -"cudbear", -"cudden", -"cuddle", -"cuddly", -"cuddy", -"cudgel", -"cudweed", -"cue", -"cueball", -"cueca", -"cueist", -"cueman", -"cuerda", -"cuesta", -"cuff", -"cuffer", -"cuffin", -"cuffy", -"cuinage", -"cuir", -"cuirass", -"cuisine", -"cuisse", -"cuissen", -"cuisten", -"cuke", -"culbut", -"culebra", -"culet", -"culeus", -"culgee", -"culicid", -"cull", -"culla", -"cullage", -"culler", -"cullet", -"culling", -"cullion", -"cullis", -"cully", -"culm", -"culmen", -"culmy", -"culotte", -"culpa", -"culpose", -"culprit", -"cult", -"cultch", -"cultic", -"cultish", -"cultism", -"cultist", -"cultual", -"culture", -"cultus", -"culver", -"culvert", -"cum", -"cumal", -"cumay", -"cumbent", -"cumber", -"cumbha", -"cumbly", -"cumbre", -"cumbu", -"cumene", -"cumenyl", -"cumhal", -"cumic", -"cumidin", -"cumin", -"cuminal", -"cuminic", -"cuminol", -"cuminyl", -"cummer", -"cummin", -"cumol", -"cump", -"cumshaw", -"cumular", -"cumuli", -"cumulus", -"cumyl", -"cuneal", -"cuneate", -"cunette", -"cuneus", -"cunila", -"cunjah", -"cunjer", -"cunner", -"cunning", -"cunye", -"cuorin", -"cup", -"cupay", -"cupcake", -"cupel", -"cupeler", -"cupful", -"cuphead", -"cupidon", -"cupless", -"cupman", -"cupmate", -"cupola", -"cupolar", -"cupped", -"cupper", -"cupping", -"cuppy", -"cuprene", -"cupric", -"cupride", -"cuprite", -"cuproid", -"cuprose", -"cuprous", -"cuprum", -"cupseed", -"cupula", -"cupule", -"cur", -"curable", -"curably", -"curacao", -"curacy", -"curare", -"curate", -"curatel", -"curatic", -"curator", -"curb", -"curber", -"curbing", -"curby", -"curcas", -"curch", -"curd", -"curdle", -"curdler", -"curdly", -"curdy", -"cure", -"curer", -"curette", -"curfew", -"curial", -"curiate", -"curie", -"curin", -"curine", -"curing", -"curio", -"curiosa", -"curioso", -"curious", -"curite", -"curium", -"curl", -"curled", -"curler", -"curlew", -"curlike", -"curlily", -"curling", -"curly", -"curn", -"curney", -"curnock", -"curple", -"curr", -"currach", -"currack", -"curragh", -"currant", -"current", -"curried", -"currier", -"currish", -"curry", -"cursal", -"curse", -"cursed", -"curser", -"curship", -"cursive", -"cursor", -"cursory", -"curst", -"curstly", -"cursus", -"curt", -"curtail", -"curtain", -"curtal", -"curtate", -"curtesy", -"curtly", -"curtsy", -"curua", -"curuba", -"curule", -"cururo", -"curvant", -"curvate", -"curve", -"curved", -"curver", -"curvet", -"curvity", -"curvous", -"curvy", -"cuscus", -"cusec", -"cush", -"cushag", -"cushat", -"cushaw", -"cushion", -"cushy", -"cusie", -"cusk", -"cusp", -"cuspal", -"cuspate", -"cusped", -"cuspid", -"cuspule", -"cuss", -"cussed", -"cusser", -"cusso", -"custard", -"custody", -"custom", -"customs", -"cut", -"cutaway", -"cutback", -"cutch", -"cutcher", -"cute", -"cutely", -"cutheal", -"cuticle", -"cutie", -"cutin", -"cutis", -"cutitis", -"cutlass", -"cutler", -"cutlery", -"cutlet", -"cutling", -"cutlips", -"cutoff", -"cutout", -"cutover", -"cuttage", -"cuttail", -"cutted", -"cutter", -"cutting", -"cuttle", -"cuttler", -"cuttoo", -"cutty", -"cutup", -"cutweed", -"cutwork", -"cutworm", -"cuvette", -"cuvy", -"cuya", -"cwierc", -"cwm", -"cyan", -"cyanate", -"cyanean", -"cyanic", -"cyanide", -"cyanin", -"cyanine", -"cyanite", -"cyanize", -"cyanol", -"cyanole", -"cyanose", -"cyanus", -"cyath", -"cyathos", -"cyathus", -"cycad", -"cyclane", -"cyclar", -"cyclas", -"cycle", -"cyclene", -"cycler", -"cyclian", -"cyclic", -"cyclide", -"cycling", -"cyclism", -"cyclist", -"cyclize", -"cycloid", -"cyclone", -"cyclope", -"cyclopy", -"cyclose", -"cyclus", -"cyesis", -"cygnet", -"cygnine", -"cyke", -"cylix", -"cyma", -"cymar", -"cymba", -"cymbal", -"cymbalo", -"cymbate", -"cyme", -"cymelet", -"cymene", -"cymling", -"cymoid", -"cymose", -"cymous", -"cymule", -"cynebot", -"cynic", -"cynical", -"cynipid", -"cynism", -"cynoid", -"cyp", -"cypre", -"cypres", -"cypress", -"cyprine", -"cypsela", -"cyrus", -"cyst", -"cystal", -"cysted", -"cystic", -"cystid", -"cystine", -"cystis", -"cystoid", -"cystoma", -"cystose", -"cystous", -"cytase", -"cytasic", -"cytitis", -"cytode", -"cytoid", -"cytoma", -"cyton", -"cytost", -"cytula", -"czar", -"czardas", -"czardom", -"czarian", -"czaric", -"czarina", -"czarish", -"czarism", -"czarist", -"d", -"da", -"daalder", -"dab", -"dabb", -"dabba", -"dabber", -"dabble", -"dabbler", -"dabby", -"dablet", -"daboia", -"daboya", -"dabster", -"dace", -"dacite", -"dacitic", -"dacker", -"dacoit", -"dacoity", -"dacryon", -"dactyl", -"dad", -"dada", -"dadap", -"dadder", -"daddle", -"daddock", -"daddy", -"dade", -"dado", -"dae", -"daedal", -"daemon", -"daemony", -"daer", -"daff", -"daffery", -"daffing", -"daffish", -"daffle", -"daffy", -"daft", -"daftly", -"dag", -"dagaba", -"dagame", -"dagassa", -"dagesh", -"dagga", -"dagger", -"daggers", -"daggle", -"daggly", -"daggy", -"daghesh", -"daglock", -"dagoba", -"dags", -"dah", -"dahoon", -"daidle", -"daidly", -"daiker", -"daikon", -"daily", -"daimen", -"daimio", -"daimon", -"dain", -"daincha", -"dainty", -"daira", -"dairi", -"dairy", -"dais", -"daisied", -"daisy", -"daitya", -"daiva", -"dak", -"daker", -"dakir", -"dal", -"dalar", -"dale", -"daleman", -"daler", -"daleth", -"dali", -"dalk", -"dallack", -"dalle", -"dalles", -"dallier", -"dally", -"dalt", -"dalteen", -"dalton", -"dam", -"dama", -"damage", -"damager", -"damages", -"daman", -"damask", -"damasse", -"dambose", -"dambrod", -"dame", -"damiana", -"damie", -"damier", -"damine", -"damlike", -"dammar", -"damme", -"dammer", -"dammish", -"damn", -"damned", -"damner", -"damnify", -"damning", -"damnous", -"damp", -"dampang", -"damped", -"dampen", -"damper", -"damping", -"dampish", -"damply", -"dampy", -"damsel", -"damson", -"dan", -"danaid", -"danaide", -"danaine", -"danaite", -"dance", -"dancer", -"dancery", -"dancing", -"dand", -"danda", -"dander", -"dandify", -"dandily", -"dandle", -"dandler", -"dandy", -"dang", -"danger", -"dangle", -"dangler", -"danglin", -"danio", -"dank", -"dankish", -"dankly", -"danli", -"danner", -"dannock", -"dansant", -"danta", -"danton", -"dao", -"daoine", -"dap", -"daphnin", -"dapicho", -"dapico", -"dapifer", -"dapper", -"dapple", -"dappled", -"dar", -"darac", -"daraf", -"darat", -"darbha", -"darby", -"dardaol", -"dare", -"dareall", -"dareful", -"darer", -"daresay", -"darg", -"dargah", -"darger", -"dargue", -"dari", -"daribah", -"daric", -"daring", -"dariole", -"dark", -"darken", -"darkful", -"darkish", -"darkle", -"darkly", -"darky", -"darling", -"darn", -"darned", -"darnel", -"darner", -"darnex", -"darning", -"daroga", -"daroo", -"darr", -"darrein", -"darst", -"dart", -"dartars", -"darter", -"darting", -"dartle", -"dartman", -"dartoic", -"dartoid", -"dartos", -"dartre", -"darts", -"darzee", -"das", -"dash", -"dashed", -"dashee", -"dasheen", -"dasher", -"dashing", -"dashpot", -"dashy", -"dasi", -"dasnt", -"dassie", -"dassy", -"dastard", -"dastur", -"dasturi", -"dasyure", -"data", -"datable", -"datably", -"dataria", -"datary", -"datch", -"datcha", -"date", -"dater", -"datil", -"dating", -"dation", -"datival", -"dative", -"dattock", -"datum", -"daturic", -"daub", -"daube", -"dauber", -"daubery", -"daubing", -"dauby", -"daud", -"daunch", -"dauncy", -"daunt", -"daunter", -"daunton", -"dauphin", -"daut", -"dautie", -"dauw", -"davach", -"daven", -"daver", -"daverdy", -"davit", -"davoch", -"davy", -"davyne", -"daw", -"dawdle", -"dawdler", -"dawdy", -"dawish", -"dawkin", -"dawn", -"dawning", -"dawny", -"dawtet", -"dawtit", -"dawut", -"day", -"dayal", -"daybeam", -"daybook", -"daydawn", -"dayfly", -"dayless", -"daylit", -"daylong", -"dayman", -"daymare", -"daymark", -"dayroom", -"days", -"daysman", -"daystar", -"daytale", -"daytide", -"daytime", -"dayward", -"daywork", -"daywrit", -"daze", -"dazed", -"dazedly", -"dazy", -"dazzle", -"dazzler", -"de", -"deacon", -"dead", -"deaden", -"deader", -"deadeye", -"deading", -"deadish", -"deadly", -"deadman", -"deadpan", -"deadpay", -"deaf", -"deafen", -"deafish", -"deafly", -"deair", -"deal", -"dealate", -"dealer", -"dealing", -"dealt", -"dean", -"deaner", -"deanery", -"deaness", -"dear", -"dearie", -"dearly", -"dearth", -"deary", -"deash", -"deasil", -"death", -"deathin", -"deathly", -"deathy", -"deave", -"deavely", -"deb", -"debacle", -"debadge", -"debar", -"debark", -"debase", -"debaser", -"debate", -"debater", -"debauch", -"debby", -"debeige", -"deben", -"debile", -"debind", -"debit", -"debord", -"debosh", -"debouch", -"debride", -"debrief", -"debris", -"debt", -"debtee", -"debtful", -"debtor", -"debunk", -"debus", -"debut", -"decad", -"decadal", -"decade", -"decadic", -"decafid", -"decagon", -"decal", -"decamp", -"decan", -"decanal", -"decane", -"decani", -"decant", -"decap", -"decapod", -"decarch", -"decare", -"decart", -"decast", -"decate", -"decator", -"decatyl", -"decay", -"decayed", -"decayer", -"decease", -"deceit", -"deceive", -"decence", -"decency", -"decene", -"decent", -"decenyl", -"decern", -"decess", -"deciare", -"decibel", -"decide", -"decided", -"decider", -"decidua", -"decil", -"decile", -"decima", -"decimal", -"deck", -"decke", -"decked", -"deckel", -"decker", -"deckie", -"decking", -"deckle", -"declaim", -"declare", -"declass", -"decline", -"declive", -"decoat", -"decoct", -"decode", -"decoic", -"decoke", -"decolor", -"decorum", -"decoy", -"decoyer", -"decream", -"decree", -"decreer", -"decreet", -"decrete", -"decrew", -"decrial", -"decried", -"decrier", -"decrown", -"decry", -"decuman", -"decuple", -"decuria", -"decurve", -"decury", -"decus", -"decyl", -"decylic", -"decyne", -"dedimus", -"dedo", -"deduce", -"deduct", -"dee", -"deed", -"deedbox", -"deedeed", -"deedful", -"deedily", -"deedy", -"deem", -"deemer", -"deemie", -"deep", -"deepen", -"deeping", -"deepish", -"deeply", -"deer", -"deerdog", -"deerlet", -"deevey", -"deface", -"defacer", -"defalk", -"defame", -"defamed", -"defamer", -"defassa", -"defat", -"default", -"defease", -"defeat", -"defect", -"defence", -"defend", -"defense", -"defer", -"defial", -"defiant", -"defiber", -"deficit", -"defier", -"defile", -"defiled", -"defiler", -"define", -"defined", -"definer", -"deflate", -"deflect", -"deflesh", -"deflex", -"defog", -"deforce", -"deform", -"defoul", -"defraud", -"defray", -"defrock", -"defrost", -"deft", -"deftly", -"defunct", -"defuse", -"defy", -"deg", -"degas", -"degauss", -"degerm", -"degged", -"degger", -"deglaze", -"degorge", -"degrade", -"degrain", -"degree", -"degu", -"degum", -"degust", -"dehair", -"dehisce", -"dehorn", -"dehors", -"dehort", -"dehull", -"dehusk", -"deice", -"deicer", -"deicide", -"deictic", -"deific", -"deifier", -"deiform", -"deify", -"deign", -"deink", -"deinos", -"deiseal", -"deism", -"deist", -"deistic", -"deity", -"deject", -"dejecta", -"dejeune", -"dekko", -"dekle", -"delaine", -"delapse", -"delate", -"delater", -"delator", -"delawn", -"delay", -"delayer", -"dele", -"delead", -"delenda", -"delete", -"delf", -"delft", -"delible", -"delict", -"delight", -"delime", -"delimit", -"delint", -"deliver", -"dell", -"deloul", -"delouse", -"delta", -"deltaic", -"deltal", -"deltic", -"deltoid", -"delude", -"deluder", -"deluge", -"deluxe", -"delve", -"delver", -"demagog", -"demal", -"demand", -"demarch", -"demark", -"demast", -"deme", -"demean", -"demency", -"dement", -"demerit", -"demesne", -"demi", -"demibob", -"demidog", -"demigod", -"demihag", -"demiman", -"demiowl", -"demiox", -"demiram", -"demirep", -"demise", -"demiss", -"demit", -"demivol", -"demob", -"demoded", -"demoid", -"demon", -"demonic", -"demonry", -"demos", -"demote", -"demotic", -"demount", -"demulce", -"demure", -"demy", -"den", -"denaro", -"denary", -"denat", -"denda", -"dendral", -"dendric", -"dendron", -"dene", -"dengue", -"denial", -"denier", -"denim", -"denizen", -"dennet", -"denote", -"dense", -"densely", -"densen", -"densher", -"densify", -"density", -"dent", -"dental", -"dentale", -"dentary", -"dentata", -"dentate", -"dentel", -"denter", -"dentex", -"dentil", -"dentile", -"dentin", -"dentine", -"dentist", -"dentoid", -"denture", -"denty", -"denude", -"denuder", -"deny", -"deodand", -"deodara", -"deota", -"depa", -"depaint", -"depark", -"depart", -"depas", -"depass", -"depend", -"depeter", -"dephase", -"depict", -"deplane", -"deplete", -"deplore", -"deploy", -"deplume", -"deplump", -"depoh", -"depone", -"deport", -"deposal", -"depose", -"deposer", -"deposit", -"depot", -"deprave", -"depress", -"deprint", -"deprive", -"depside", -"depth", -"depthen", -"depute", -"deputy", -"dequeen", -"derah", -"deraign", -"derail", -"derange", -"derat", -"derate", -"derater", -"deray", -"derby", -"dere", -"dereism", -"deric", -"deride", -"derider", -"derival", -"derive", -"derived", -"deriver", -"derm", -"derma", -"dermad", -"dermal", -"dermic", -"dermis", -"dermoid", -"dermol", -"dern", -"dernier", -"derout", -"derrick", -"derride", -"derries", -"derry", -"dertrum", -"derust", -"dervish", -"desalt", -"desand", -"descale", -"descant", -"descend", -"descent", -"descort", -"descry", -"deseed", -"deseret", -"desert", -"deserve", -"desex", -"desi", -"desight", -"design", -"desire", -"desired", -"desirer", -"desist", -"desize", -"desk", -"deslime", -"desma", -"desman", -"desmic", -"desmid", -"desmine", -"desmoid", -"desmoma", -"desmon", -"despair", -"despect", -"despise", -"despite", -"despoil", -"despond", -"despot", -"dess", -"dessa", -"dessert", -"dessil", -"destain", -"destine", -"destiny", -"destour", -"destroy", -"desuete", -"desugar", -"desyl", -"detach", -"detail", -"detain", -"detar", -"detax", -"detect", -"detent", -"deter", -"deterge", -"detest", -"detin", -"detinet", -"detinue", -"detour", -"detract", -"detrain", -"detrude", -"detune", -"detur", -"deuce", -"deuced", -"deul", -"deuton", -"dev", -"deva", -"devall", -"devalue", -"devance", -"devast", -"devata", -"develin", -"develop", -"devest", -"deviant", -"deviate", -"device", -"devil", -"deviled", -"deviler", -"devilet", -"devilry", -"devily", -"devious", -"devisal", -"devise", -"devisee", -"deviser", -"devisor", -"devoice", -"devoid", -"devoir", -"devolve", -"devote", -"devoted", -"devotee", -"devoter", -"devour", -"devout", -"devow", -"devvel", -"dew", -"dewan", -"dewanee", -"dewater", -"dewax", -"dewbeam", -"dewclaw", -"dewcup", -"dewdamp", -"dewdrop", -"dewer", -"dewfall", -"dewily", -"dewlap", -"dewless", -"dewlike", -"dewool", -"deworm", -"dewret", -"dewtry", -"dewworm", -"dewy", -"dexter", -"dextrad", -"dextral", -"dextran", -"dextrin", -"dextro", -"dey", -"deyship", -"dezinc", -"dha", -"dhabb", -"dhai", -"dhak", -"dhamnoo", -"dhan", -"dhangar", -"dhanuk", -"dhanush", -"dharana", -"dharani", -"dharma", -"dharna", -"dhaura", -"dhauri", -"dhava", -"dhaw", -"dheri", -"dhobi", -"dhole", -"dhoni", -"dhoon", -"dhoti", -"dhoul", -"dhow", -"dhu", -"dhunchi", -"dhurra", -"dhyal", -"dhyana", -"di", -"diabase", -"diacid", -"diacle", -"diacope", -"diact", -"diactin", -"diadem", -"diaderm", -"diaene", -"diagram", -"dial", -"dialect", -"dialer", -"dialin", -"dialing", -"dialist", -"dialkyl", -"diallel", -"diallyl", -"dialyze", -"diamb", -"diambic", -"diamide", -"diamine", -"diamond", -"dian", -"diander", -"dianite", -"diapase", -"diapasm", -"diaper", -"diaplex", -"diapsid", -"diarch", -"diarchy", -"diarial", -"diarian", -"diarist", -"diarize", -"diary", -"diastem", -"diaster", -"diasyrm", -"diatom", -"diaulic", -"diaulos", -"diaxial", -"diaxon", -"diazide", -"diazine", -"diazoic", -"diazole", -"diazoma", -"dib", -"dibase", -"dibasic", -"dibatag", -"dibber", -"dibble", -"dibbler", -"dibbuk", -"dibhole", -"dibrach", -"dibrom", -"dibs", -"dicast", -"dice", -"dicebox", -"dicecup", -"diceman", -"dicer", -"dicetyl", -"dich", -"dichas", -"dichord", -"dicing", -"dick", -"dickens", -"dicker", -"dickey", -"dicky", -"dicolic", -"dicolon", -"dicot", -"dicotyl", -"dicta", -"dictate", -"dictic", -"diction", -"dictum", -"dicycle", -"did", -"didder", -"diddle", -"diddler", -"diddy", -"didelph", -"didie", -"didine", -"didle", -"didna", -"didnt", -"didromy", -"didst", -"didym", -"didymia", -"didymus", -"die", -"dieb", -"dieback", -"diedral", -"diedric", -"diehard", -"dielike", -"diem", -"diene", -"dier", -"diesel", -"diesis", -"diet", -"dietal", -"dietary", -"dieter", -"diethyl", -"dietic", -"dietics", -"dietine", -"dietist", -"diewise", -"diffame", -"differ", -"diffide", -"difform", -"diffuse", -"dig", -"digamma", -"digamy", -"digenic", -"digeny", -"digest", -"digger", -"digging", -"dight", -"dighter", -"digit", -"digital", -"digitus", -"diglot", -"diglyph", -"digmeat", -"dignify", -"dignity", -"digram", -"digraph", -"digress", -"digs", -"dihalo", -"diiamb", -"diiodo", -"dika", -"dikage", -"dike", -"diker", -"diketo", -"dikkop", -"dilate", -"dilated", -"dilater", -"dilator", -"dildo", -"dilemma", -"dilker", -"dill", -"dilli", -"dillier", -"dilling", -"dillue", -"dilluer", -"dilly", -"dilo", -"dilogy", -"diluent", -"dilute", -"diluted", -"dilutee", -"diluter", -"dilutor", -"diluvia", -"dim", -"dimber", -"dimble", -"dime", -"dimer", -"dimeran", -"dimeric", -"dimeter", -"dimiss", -"dimit", -"dimity", -"dimly", -"dimmed", -"dimmer", -"dimmest", -"dimmet", -"dimmish", -"dimness", -"dimoric", -"dimorph", -"dimple", -"dimply", -"dimps", -"dimpsy", -"din", -"dinar", -"dinder", -"dindle", -"dine", -"diner", -"dineric", -"dinero", -"dinette", -"ding", -"dingar", -"dingbat", -"dinge", -"dingee", -"dinghee", -"dinghy", -"dingily", -"dingle", -"dingly", -"dingo", -"dingus", -"dingy", -"dinic", -"dinical", -"dining", -"dinitro", -"dink", -"dinkey", -"dinkum", -"dinky", -"dinmont", -"dinner", -"dinnery", -"dinomic", -"dinsome", -"dint", -"dinus", -"diobely", -"diobol", -"diocese", -"diode", -"diodont", -"dioecy", -"diol", -"dionise", -"dionym", -"diopter", -"dioptra", -"dioptry", -"diorama", -"diorite", -"diose", -"diosmin", -"diota", -"diotic", -"dioxane", -"dioxide", -"dioxime", -"dioxy", -"dip", -"dipetto", -"diphase", -"diphead", -"diplex", -"diploe", -"diploic", -"diploid", -"diplois", -"diploma", -"diplont", -"diplopy", -"dipnoan", -"dipnoid", -"dipode", -"dipodic", -"dipody", -"dipolar", -"dipole", -"diporpa", -"dipped", -"dipper", -"dipping", -"dipsas", -"dipsey", -"dipter", -"diptote", -"diptych", -"dipware", -"dipygus", -"dipylon", -"dipyre", -"dird", -"dirdum", -"dire", -"direct", -"direful", -"direly", -"dirempt", -"dirge", -"dirgler", -"dirhem", -"dirk", -"dirl", -"dirndl", -"dirt", -"dirten", -"dirtily", -"dirty", -"dis", -"disable", -"disagio", -"disally", -"disarm", -"disavow", -"disawa", -"disazo", -"disband", -"disbar", -"disbark", -"disbody", -"disbud", -"disbury", -"disc", -"discage", -"discal", -"discard", -"discase", -"discept", -"discern", -"discerp", -"discoid", -"discord", -"discous", -"discus", -"discuss", -"disdain", -"disdub", -"disease", -"disedge", -"diseme", -"disemic", -"disfame", -"disfen", -"disgig", -"disglut", -"disgood", -"disgown", -"disgulf", -"disgust", -"dish", -"dished", -"dishelm", -"disher", -"dishful", -"dishome", -"dishorn", -"dishpan", -"dishrag", -"disject", -"disjoin", -"disjune", -"disk", -"disleaf", -"dislike", -"dislimn", -"dislink", -"dislip", -"disload", -"dislove", -"dismain", -"dismal", -"disman", -"dismark", -"dismask", -"dismast", -"dismay", -"disme", -"dismiss", -"disna", -"disnest", -"disnew", -"disobey", -"disodic", -"disomic", -"disomus", -"disorb", -"disown", -"dispark", -"dispart", -"dispel", -"dispend", -"display", -"dispone", -"dispope", -"disport", -"dispose", -"dispost", -"dispulp", -"dispute", -"disrank", -"disrate", -"disring", -"disrobe", -"disroof", -"disroot", -"disrump", -"disrupt", -"diss", -"disseat", -"dissect", -"dissent", -"dissert", -"dissoul", -"dissuit", -"distad", -"distaff", -"distain", -"distal", -"distale", -"distant", -"distend", -"distent", -"distich", -"distill", -"distome", -"distort", -"distune", -"disturb", -"disturn", -"disuse", -"diswood", -"disyoke", -"dit", -"dita", -"dital", -"ditch", -"ditcher", -"dite", -"diter", -"dither", -"dithery", -"dithion", -"ditolyl", -"ditone", -"dittamy", -"dittany", -"dittay", -"dittied", -"ditto", -"ditty", -"diurnal", -"diurne", -"div", -"diva", -"divan", -"divata", -"dive", -"divel", -"diver", -"diverge", -"divers", -"diverse", -"divert", -"divest", -"divide", -"divided", -"divider", -"divine", -"diviner", -"diving", -"divinyl", -"divisor", -"divorce", -"divot", -"divoto", -"divulge", -"divulse", -"divus", -"divvy", -"diwata", -"dixie", -"dixit", -"dixy", -"dizain", -"dizen", -"dizoic", -"dizzard", -"dizzily", -"dizzy", -"djave", -"djehad", -"djerib", -"djersa", -"do", -"doab", -"doable", -"doarium", -"doat", -"doated", -"doater", -"doating", -"doatish", -"dob", -"dobbed", -"dobber", -"dobbin", -"dobbing", -"dobby", -"dobe", -"dobla", -"doblon", -"dobra", -"dobrao", -"dobson", -"doby", -"doc", -"docent", -"docible", -"docile", -"docity", -"dock", -"dockage", -"docken", -"docker", -"docket", -"dockize", -"dockman", -"docmac", -"doctor", -"doctrix", -"dod", -"dodd", -"doddart", -"dodded", -"dodder", -"doddery", -"doddie", -"dodding", -"doddle", -"doddy", -"dodecyl", -"dodge", -"dodger", -"dodgery", -"dodgily", -"dodgy", -"dodkin", -"dodlet", -"dodman", -"dodo", -"dodoism", -"dodrans", -"doe", -"doebird", -"doeglic", -"doer", -"does", -"doeskin", -"doesnt", -"doest", -"doff", -"doffer", -"dog", -"dogal", -"dogate", -"dogbane", -"dogbite", -"dogblow", -"dogboat", -"dogbolt", -"dogbush", -"dogcart", -"dogdom", -"doge", -"dogedom", -"dogface", -"dogfall", -"dogfish", -"dogfoot", -"dogged", -"dogger", -"doggery", -"doggess", -"doggish", -"doggo", -"doggone", -"doggrel", -"doggy", -"doghead", -"doghole", -"doghood", -"dogie", -"dogless", -"doglike", -"dogly", -"dogma", -"dogman", -"dogmata", -"dogs", -"dogship", -"dogskin", -"dogtail", -"dogtie", -"dogtrot", -"dogvane", -"dogwood", -"dogy", -"doigt", -"doiled", -"doily", -"doina", -"doing", -"doings", -"doit", -"doited", -"doitkin", -"doke", -"dokhma", -"dola", -"dolabra", -"dolcan", -"dolcian", -"dolcino", -"doldrum", -"dole", -"doleful", -"dolent", -"doless", -"doli", -"dolia", -"dolina", -"doline", -"dolium", -"doll", -"dollar", -"dolldom", -"dollier", -"dollish", -"dollop", -"dolly", -"dolman", -"dolmen", -"dolor", -"dolose", -"dolous", -"dolphin", -"dolt", -"doltish", -"dom", -"domain", -"domal", -"domba", -"dome", -"doment", -"domer", -"domett", -"domic", -"domical", -"domine", -"dominie", -"domino", -"dominus", -"domite", -"domitic", -"domn", -"domnei", -"domoid", -"dompt", -"domy", -"don", -"donable", -"donary", -"donate", -"donated", -"donatee", -"donator", -"donax", -"done", -"donee", -"doney", -"dong", -"donga", -"dongon", -"donjon", -"donkey", -"donna", -"donnert", -"donnish", -"donnism", -"donnot", -"donor", -"donship", -"donsie", -"dont", -"donum", -"doob", -"doocot", -"doodab", -"doodad", -"doodle", -"doodler", -"dooja", -"dook", -"dooket", -"dookit", -"dool", -"doolee", -"dooley", -"dooli", -"doolie", -"dooly", -"doom", -"doomage", -"doomer", -"doomful", -"dooms", -"doon", -"door", -"doorba", -"doorboy", -"doored", -"doorman", -"doorway", -"dop", -"dopa", -"dopatta", -"dope", -"doper", -"dopey", -"dopper", -"doppia", -"dor", -"dorab", -"dorad", -"dorado", -"doree", -"dorhawk", -"doria", -"dorje", -"dorlach", -"dorlot", -"dorm", -"dormant", -"dormer", -"dormie", -"dormy", -"dorn", -"dorneck", -"dornic", -"dornick", -"dornock", -"dorp", -"dorsad", -"dorsal", -"dorsale", -"dorsel", -"dorser", -"dorsum", -"dorter", -"dorts", -"dorty", -"doruck", -"dory", -"dos", -"dosa", -"dosadh", -"dosage", -"dose", -"doser", -"dosis", -"doss", -"dossal", -"dossel", -"dosser", -"dossier", -"dossil", -"dossman", -"dot", -"dotage", -"dotal", -"dotard", -"dotardy", -"dotate", -"dotchin", -"dote", -"doted", -"doter", -"doting", -"dotish", -"dotkin", -"dotless", -"dotlike", -"dotted", -"dotter", -"dottily", -"dotting", -"dottle", -"dottler", -"dotty", -"doty", -"douar", -"double", -"doubled", -"doubler", -"doublet", -"doubly", -"doubt", -"doubter", -"douc", -"douce", -"doucely", -"doucet", -"douche", -"doucin", -"doucine", -"doudle", -"dough", -"dought", -"doughty", -"doughy", -"doum", -"doup", -"douping", -"dour", -"dourine", -"dourly", -"douse", -"douser", -"dout", -"douter", -"doutous", -"dove", -"dovecot", -"dovekey", -"dovekie", -"dovelet", -"dover", -"dovish", -"dow", -"dowable", -"dowager", -"dowcet", -"dowd", -"dowdily", -"dowdy", -"dowed", -"dowel", -"dower", -"doweral", -"dowery", -"dowf", -"dowie", -"dowily", -"dowitch", -"dowl", -"dowlas", -"dowless", -"down", -"downby", -"downcry", -"downcut", -"downer", -"downily", -"downlie", -"downset", -"downway", -"downy", -"dowp", -"dowry", -"dowse", -"dowser", -"dowset", -"doxa", -"doxy", -"doze", -"dozed", -"dozen", -"dozener", -"dozenth", -"dozer", -"dozily", -"dozy", -"dozzled", -"drab", -"drabbet", -"drabble", -"drabby", -"drably", -"drachm", -"drachma", -"dracma", -"draff", -"draffy", -"draft", -"draftee", -"drafter", -"drafty", -"drag", -"dragade", -"dragbar", -"dragged", -"dragger", -"draggle", -"draggly", -"draggy", -"dragman", -"dragnet", -"drago", -"dragon", -"dragoon", -"dragsaw", -"drail", -"drain", -"draine", -"drained", -"drainer", -"drake", -"dram", -"drama", -"dramm", -"dramme", -"drammed", -"drammer", -"drang", -"drank", -"drant", -"drape", -"draper", -"drapery", -"drassid", -"drastic", -"drat", -"drate", -"dratted", -"draught", -"dravya", -"draw", -"drawarm", -"drawbar", -"drawboy", -"drawcut", -"drawee", -"drawer", -"drawers", -"drawing", -"drawk", -"drawl", -"drawler", -"drawly", -"drawn", -"drawnet", -"drawoff", -"drawout", -"drawrod", -"dray", -"drayage", -"drayman", -"drazel", -"dread", -"dreader", -"dreadly", -"dream", -"dreamer", -"dreamsy", -"dreamt", -"dreamy", -"drear", -"drearly", -"dreary", -"dredge", -"dredger", -"dree", -"dreep", -"dreepy", -"dreg", -"dreggy", -"dregs", -"drench", -"dreng", -"dress", -"dressed", -"dresser", -"dressy", -"drest", -"drew", -"drewite", -"drias", -"drib", -"dribble", -"driblet", -"driddle", -"dried", -"drier", -"driest", -"drift", -"drifter", -"drifty", -"drill", -"driller", -"drillet", -"dringle", -"drink", -"drinker", -"drinn", -"drip", -"dripper", -"dripple", -"drippy", -"drisk", -"drivage", -"drive", -"drivel", -"driven", -"driver", -"driving", -"drizzle", -"drizzly", -"droddum", -"drogh", -"drogher", -"drogue", -"droit", -"droll", -"drolly", -"drome", -"dromic", -"dromond", -"dromos", -"drona", -"dronage", -"drone", -"droner", -"drongo", -"dronish", -"drony", -"drool", -"droop", -"drooper", -"droopt", -"droopy", -"drop", -"droplet", -"dropman", -"dropout", -"dropper", -"droppy", -"dropsy", -"dropt", -"droshky", -"drosky", -"dross", -"drossel", -"drosser", -"drossy", -"drostdy", -"droud", -"drought", -"drouk", -"drove", -"drover", -"drovy", -"drow", -"drown", -"drowner", -"drowse", -"drowsy", -"drub", -"drubber", -"drubbly", -"drucken", -"drudge", -"drudger", -"druery", -"drug", -"drugger", -"drugget", -"druggy", -"drugman", -"druid", -"druidic", -"druidry", -"druith", -"drum", -"drumble", -"drumlin", -"drumly", -"drummer", -"drummy", -"drung", -"drungar", -"drunk", -"drunken", -"drupal", -"drupe", -"drupel", -"druse", -"drusy", -"druxy", -"dry", -"dryad", -"dryadic", -"dryas", -"drycoal", -"dryfoot", -"drying", -"dryish", -"dryly", -"dryness", -"dryster", -"dryth", -"duad", -"duadic", -"dual", -"duali", -"dualin", -"dualism", -"dualist", -"duality", -"dualize", -"dually", -"duarch", -"duarchy", -"dub", -"dubash", -"dubb", -"dubba", -"dubbah", -"dubber", -"dubbing", -"dubby", -"dubiety", -"dubious", -"dubs", -"ducal", -"ducally", -"ducape", -"ducat", -"ducato", -"ducdame", -"duces", -"duchess", -"duchy", -"duck", -"ducker", -"duckery", -"duckie", -"ducking", -"duckpin", -"duct", -"ducted", -"ductile", -"duction", -"ductor", -"ductule", -"dud", -"dudaim", -"dudder", -"duddery", -"duddies", -"dude", -"dudeen", -"dudgeon", -"dudine", -"dudish", -"dudism", -"dudler", -"dudley", -"dudman", -"due", -"duel", -"dueler", -"dueling", -"duelist", -"duello", -"dueness", -"duenna", -"duer", -"duet", -"duff", -"duffel", -"duffer", -"duffing", -"dufoil", -"dufter", -"duftery", -"dug", -"dugal", -"dugdug", -"duggler", -"dugong", -"dugout", -"dugway", -"duhat", -"duiker", -"duim", -"duit", -"dujan", -"duke", -"dukedom", -"dukely", -"dukery", -"dukhn", -"dukker", -"dulbert", -"dulcet", -"dulcian", -"dulcify", -"dulcose", -"duledge", -"duler", -"dulia", -"dull", -"dullard", -"duller", -"dullery", -"dullify", -"dullish", -"dullity", -"dully", -"dulosis", -"dulotic", -"dulse", -"dult", -"dultie", -"duly", -"dum", -"duma", -"dumaist", -"dumb", -"dumba", -"dumbcow", -"dumbly", -"dumdum", -"dummel", -"dummy", -"dumose", -"dump", -"dumpage", -"dumper", -"dumpily", -"dumping", -"dumpish", -"dumple", -"dumpoke", -"dumpy", -"dumsola", -"dun", -"dunair", -"dunal", -"dunbird", -"dunce", -"duncery", -"dunch", -"duncify", -"duncish", -"dunder", -"dune", -"dunfish", -"dung", -"dungeon", -"dunger", -"dungol", -"dungon", -"dungy", -"dunite", -"dunk", -"dunker", -"dunlin", -"dunnage", -"dunne", -"dunner", -"dunness", -"dunnish", -"dunnite", -"dunnock", -"dunny", -"dunst", -"dunt", -"duntle", -"duny", -"duo", -"duodena", -"duodene", -"duole", -"duopod", -"duopoly", -"duotone", -"duotype", -"dup", -"dupable", -"dupe", -"dupedom", -"duper", -"dupery", -"dupion", -"dupla", -"duple", -"duplet", -"duplex", -"duplify", -"duplone", -"duppy", -"dura", -"durable", -"durably", -"durain", -"dural", -"duramen", -"durance", -"durant", -"durax", -"durbar", -"dure", -"durene", -"durenol", -"duress", -"durgan", -"durian", -"during", -"durity", -"durmast", -"durn", -"duro", -"durra", -"durrie", -"durrin", -"durry", -"durst", -"durwaun", -"duryl", -"dusack", -"duscle", -"dush", -"dusio", -"dusk", -"dusken", -"duskily", -"duskish", -"duskly", -"dusky", -"dust", -"dustbin", -"dustbox", -"dustee", -"duster", -"dustily", -"dusting", -"dustman", -"dustpan", -"dustuck", -"dusty", -"dutch", -"duteous", -"dutied", -"dutiful", -"dutra", -"duty", -"duumvir", -"duvet", -"duvetyn", -"dux", -"duyker", -"dvaita", -"dvandva", -"dwale", -"dwalm", -"dwang", -"dwarf", -"dwarfy", -"dwell", -"dwelled", -"dweller", -"dwelt", -"dwindle", -"dwine", -"dyad", -"dyadic", -"dyarchy", -"dyaster", -"dyce", -"dye", -"dyeable", -"dyeing", -"dyer", -"dyester", -"dyeware", -"dyeweed", -"dyewood", -"dying", -"dyingly", -"dyke", -"dyker", -"dynamic", -"dynamis", -"dynamo", -"dynast", -"dynasty", -"dyne", -"dyphone", -"dyslogy", -"dysnomy", -"dyspnea", -"dystome", -"dysuria", -"dysuric", -"dzeren", -"e", -"ea", -"each", -"eager", -"eagerly", -"eagle", -"eagless", -"eaglet", -"eagre", -"ean", -"ear", -"earache", -"earbob", -"earcap", -"eardrop", -"eardrum", -"eared", -"earful", -"earhole", -"earing", -"earl", -"earlap", -"earldom", -"earless", -"earlet", -"earlike", -"earlish", -"earlock", -"early", -"earmark", -"earn", -"earner", -"earnest", -"earnful", -"earning", -"earpick", -"earplug", -"earring", -"earshot", -"earsore", -"eartab", -"earth", -"earthed", -"earthen", -"earthly", -"earthy", -"earwax", -"earwig", -"earworm", -"earwort", -"ease", -"easeful", -"easel", -"easer", -"easier", -"easiest", -"easily", -"easing", -"east", -"easter", -"eastern", -"easting", -"easy", -"eat", -"eatable", -"eatage", -"eaten", -"eater", -"eatery", -"eating", -"eats", -"eave", -"eaved", -"eaver", -"eaves", -"ebb", -"ebbman", -"eboe", -"ebon", -"ebonist", -"ebonite", -"ebonize", -"ebony", -"ebriate", -"ebriety", -"ebrious", -"ebulus", -"eburine", -"ecad", -"ecanda", -"ecarte", -"ecbatic", -"ecbole", -"ecbolic", -"ecdemic", -"ecderon", -"ecdysis", -"ecesic", -"ecesis", -"eche", -"echea", -"echelon", -"echidna", -"echinal", -"echinid", -"echinus", -"echo", -"echoer", -"echoic", -"echoism", -"echoist", -"echoize", -"ecize", -"ecklein", -"eclair", -"eclat", -"eclegm", -"eclegma", -"eclipse", -"eclogue", -"ecoid", -"ecole", -"ecology", -"economy", -"ecotone", -"ecotype", -"ecphore", -"ecru", -"ecstasy", -"ectad", -"ectal", -"ectally", -"ectasia", -"ectasis", -"ectatic", -"ectene", -"ecthyma", -"ectiris", -"ectopia", -"ectopic", -"ectopy", -"ectozoa", -"ectypal", -"ectype", -"eczema", -"edacity", -"edaphic", -"edaphon", -"edder", -"eddish", -"eddo", -"eddy", -"edea", -"edeagra", -"edeitis", -"edema", -"edemic", -"edenite", -"edental", -"edestan", -"edestin", -"edge", -"edged", -"edgeman", -"edger", -"edging", -"edgrew", -"edgy", -"edh", -"edible", -"edict", -"edictal", -"edicule", -"edifice", -"edifier", -"edify", -"edit", -"edital", -"edition", -"editor", -"educand", -"educate", -"educe", -"educive", -"educt", -"eductor", -"eegrass", -"eel", -"eelboat", -"eelbob", -"eelcake", -"eeler", -"eelery", -"eelfare", -"eelfish", -"eellike", -"eelpot", -"eelpout", -"eelshop", -"eelskin", -"eelware", -"eelworm", -"eely", -"eer", -"eerie", -"eerily", -"effable", -"efface", -"effacer", -"effect", -"effects", -"effendi", -"effete", -"effigy", -"efflate", -"efflux", -"efform", -"effort", -"effulge", -"effund", -"effuse", -"eft", -"eftest", -"egad", -"egality", -"egence", -"egeran", -"egest", -"egesta", -"egg", -"eggcup", -"egger", -"eggfish", -"egghead", -"egghot", -"egging", -"eggler", -"eggless", -"egglike", -"eggnog", -"eggy", -"egilops", -"egipto", -"egma", -"ego", -"egohood", -"egoism", -"egoist", -"egoity", -"egoize", -"egoizer", -"egol", -"egomism", -"egotism", -"egotist", -"egotize", -"egress", -"egret", -"eh", -"eheu", -"ehlite", -"ehuawa", -"eident", -"eider", -"eidetic", -"eidolic", -"eidolon", -"eight", -"eighth", -"eighty", -"eigne", -"eimer", -"einkorn", -"eisodic", -"either", -"eject", -"ejecta", -"ejector", -"ejoo", -"ekaha", -"eke", -"eker", -"ekerite", -"eking", -"ekka", -"ekphore", -"ektene", -"ektenes", -"el", -"elaidic", -"elaidin", -"elain", -"elaine", -"elance", -"eland", -"elanet", -"elapid", -"elapine", -"elapoid", -"elapse", -"elastic", -"elastin", -"elatcha", -"elate", -"elated", -"elater", -"elation", -"elative", -"elator", -"elb", -"elbow", -"elbowed", -"elbower", -"elbowy", -"elcaja", -"elchee", -"eld", -"elder", -"elderly", -"eldest", -"eldin", -"elding", -"eldress", -"elect", -"electee", -"electly", -"elector", -"electro", -"elegant", -"elegiac", -"elegist", -"elegit", -"elegize", -"elegy", -"eleidin", -"element", -"elemi", -"elemin", -"elench", -"elenchi", -"elenge", -"elevate", -"eleven", -"elevon", -"elf", -"elfhood", -"elfic", -"elfin", -"elfish", -"elfkin", -"elfland", -"elflike", -"elflock", -"elfship", -"elfwife", -"elfwort", -"elicit", -"elide", -"elision", -"elisor", -"elite", -"elixir", -"elk", -"elkhorn", -"elkslip", -"elkwood", -"ell", -"ellagic", -"elle", -"elleck", -"ellfish", -"ellipse", -"ellops", -"ellwand", -"elm", -"elmy", -"elocute", -"elod", -"eloge", -"elogium", -"eloign", -"elope", -"eloper", -"elops", -"els", -"else", -"elsehow", -"elsin", -"elt", -"eluate", -"elude", -"eluder", -"elusion", -"elusive", -"elusory", -"elute", -"elution", -"elutor", -"eluvial", -"eluvium", -"elvan", -"elver", -"elves", -"elvet", -"elvish", -"elysia", -"elytral", -"elytrin", -"elytron", -"elytrum", -"em", -"emanant", -"emanate", -"emanium", -"emarcid", -"emball", -"embalm", -"embank", -"embar", -"embargo", -"embark", -"embassy", -"embathe", -"embay", -"embed", -"embelic", -"ember", -"embind", -"embira", -"emblaze", -"emblem", -"emblema", -"emblic", -"embody", -"embog", -"embole", -"embolic", -"embolo", -"embolum", -"embolus", -"emboly", -"embosom", -"emboss", -"embound", -"embow", -"embowed", -"embowel", -"embower", -"embox", -"embrace", -"embrail", -"embroil", -"embrown", -"embryo", -"embryon", -"embuia", -"embus", -"embusk", -"emcee", -"eme", -"emeer", -"emend", -"emender", -"emerald", -"emerge", -"emerize", -"emerse", -"emersed", -"emery", -"emesis", -"emetic", -"emetine", -"emgalla", -"emigree", -"eminent", -"emir", -"emirate", -"emit", -"emitter", -"emma", -"emmenic", -"emmer", -"emmet", -"emodin", -"emoloa", -"emote", -"emotion", -"emotive", -"empall", -"empanel", -"empaper", -"empark", -"empasm", -"empathy", -"emperor", -"empery", -"empire", -"empiric", -"emplace", -"emplane", -"employ", -"emplume", -"emporia", -"empower", -"empress", -"emprise", -"empt", -"emptier", -"emptily", -"emptins", -"emption", -"emptor", -"empty", -"empyema", -"emu", -"emulant", -"emulate", -"emulous", -"emulsin", -"emulsor", -"emyd", -"emydian", -"en", -"enable", -"enabler", -"enact", -"enactor", -"enaena", -"enage", -"enalid", -"enam", -"enamber", -"enamdar", -"enamel", -"enamor", -"enapt", -"enarbor", -"enarch", -"enarm", -"enarme", -"enate", -"enatic", -"enation", -"enbrave", -"encage", -"encake", -"encamp", -"encase", -"encash", -"encauma", -"encave", -"encell", -"enchain", -"enchair", -"enchant", -"enchase", -"enchest", -"encina", -"encinal", -"encist", -"enclasp", -"enclave", -"encloak", -"enclose", -"encloud", -"encoach", -"encode", -"encoil", -"encolor", -"encomia", -"encomic", -"encoop", -"encore", -"encowl", -"encraal", -"encraty", -"encreel", -"encrisp", -"encrown", -"encrust", -"encrypt", -"encup", -"encurl", -"encyst", -"end", -"endable", -"endarch", -"endaze", -"endear", -"ended", -"endemic", -"ender", -"endere", -"enderon", -"endevil", -"endew", -"endgate", -"ending", -"endite", -"endive", -"endless", -"endlong", -"endmost", -"endogen", -"endome", -"endopod", -"endoral", -"endore", -"endorse", -"endoss", -"endotys", -"endow", -"endower", -"endozoa", -"endue", -"endura", -"endure", -"endurer", -"endways", -"endwise", -"endyma", -"endymal", -"endysis", -"enema", -"enemy", -"energic", -"energid", -"energy", -"eneuch", -"eneugh", -"enface", -"enfelon", -"enfeoff", -"enfever", -"enfile", -"enfiled", -"enflesh", -"enfoil", -"enfold", -"enforce", -"enfork", -"enfoul", -"enframe", -"enfree", -"engage", -"engaged", -"engager", -"engaol", -"engarb", -"engaud", -"engaze", -"engem", -"engild", -"engine", -"engird", -"engirt", -"englad", -"englobe", -"engloom", -"englory", -"englut", -"englyn", -"engobe", -"engold", -"engore", -"engorge", -"engrace", -"engraff", -"engraft", -"engrail", -"engrain", -"engram", -"engrasp", -"engrave", -"engreen", -"engross", -"enguard", -"engulf", -"enhalo", -"enhance", -"enhat", -"enhaunt", -"enheart", -"enhedge", -"enhelm", -"enherit", -"enhusk", -"eniac", -"enigma", -"enisle", -"enjail", -"enjamb", -"enjelly", -"enjewel", -"enjoin", -"enjoy", -"enjoyer", -"enkraal", -"enlace", -"enlard", -"enlarge", -"enleaf", -"enlief", -"enlife", -"enlight", -"enlink", -"enlist", -"enliven", -"enlock", -"enlodge", -"enmask", -"enmass", -"enmesh", -"enmist", -"enmity", -"enmoss", -"ennead", -"ennerve", -"enniche", -"ennoble", -"ennoic", -"ennomic", -"ennui", -"enocyte", -"enodal", -"enoil", -"enol", -"enolate", -"enolic", -"enolize", -"enomoty", -"enoplan", -"enorm", -"enough", -"enounce", -"enow", -"enplane", -"enquire", -"enquiry", -"enrace", -"enrage", -"enraged", -"enrange", -"enrank", -"enrapt", -"enray", -"enrib", -"enrich", -"enring", -"enrive", -"enrobe", -"enrober", -"enrol", -"enroll", -"enroot", -"enrough", -"enruin", -"enrut", -"ens", -"ensaint", -"ensand", -"ensate", -"enscene", -"ense", -"enseam", -"enseat", -"enseem", -"enserf", -"ensete", -"enshade", -"enshawl", -"enshell", -"ensign", -"ensile", -"ensky", -"enslave", -"ensmall", -"ensnare", -"ensnarl", -"ensnow", -"ensoul", -"enspell", -"enstamp", -"enstar", -"enstate", -"ensteel", -"enstool", -"enstore", -"ensuant", -"ensue", -"ensuer", -"ensure", -"ensurer", -"ensweep", -"entach", -"entad", -"entail", -"ental", -"entame", -"entasia", -"entasis", -"entelam", -"entente", -"enter", -"enteral", -"enterer", -"enteria", -"enteric", -"enteron", -"entheal", -"enthral", -"enthuse", -"entia", -"entice", -"enticer", -"entify", -"entire", -"entiris", -"entitle", -"entity", -"entoil", -"entomb", -"entomic", -"entone", -"entopic", -"entotic", -"entozoa", -"entrail", -"entrain", -"entrant", -"entrap", -"entreat", -"entree", -"entropy", -"entrust", -"entry", -"entwine", -"entwist", -"enure", -"enurny", -"envapor", -"envault", -"enveil", -"envelop", -"envenom", -"envied", -"envier", -"envious", -"environ", -"envoy", -"envy", -"envying", -"enwiden", -"enwind", -"enwisen", -"enwoman", -"enwomb", -"enwood", -"enwound", -"enwrap", -"enwrite", -"enzone", -"enzooty", -"enzym", -"enzyme", -"enzymic", -"eoan", -"eolith", -"eon", -"eonism", -"eophyte", -"eosate", -"eoside", -"eosin", -"eosinic", -"eozoon", -"epacme", -"epacrid", -"epact", -"epactal", -"epagoge", -"epanody", -"eparch", -"eparchy", -"epaule", -"epaulet", -"epaxial", -"epee", -"epeeist", -"epeiric", -"epeirid", -"epergne", -"epha", -"ephah", -"ephebe", -"ephebic", -"ephebos", -"ephebus", -"ephelis", -"ephetae", -"ephete", -"ephetic", -"ephod", -"ephor", -"ephoral", -"ephoric", -"ephorus", -"ephyra", -"epibole", -"epiboly", -"epic", -"epical", -"epicarp", -"epicede", -"epicele", -"epicene", -"epichil", -"epicism", -"epicist", -"epicly", -"epicure", -"epicyte", -"epidemy", -"epiderm", -"epidote", -"epigeal", -"epigean", -"epigeic", -"epigene", -"epigone", -"epigram", -"epigyne", -"epigyny", -"epihyal", -"epikeia", -"epilate", -"epilobe", -"epimer", -"epimere", -"epimyth", -"epinaos", -"epinine", -"epiotic", -"epipial", -"episode", -"epistle", -"epitaph", -"epitela", -"epithem", -"epithet", -"epitoke", -"epitome", -"epiural", -"epizoa", -"epizoal", -"epizoan", -"epizoic", -"epizoon", -"epoch", -"epocha", -"epochal", -"epode", -"epodic", -"eponym", -"eponymy", -"epopee", -"epopt", -"epoptes", -"epoptic", -"epos", -"epsilon", -"epulary", -"epulis", -"epulo", -"epuloid", -"epural", -"epurate", -"equable", -"equably", -"equal", -"equally", -"equant", -"equate", -"equator", -"equerry", -"equid", -"equine", -"equinia", -"equinox", -"equinus", -"equip", -"equiped", -"equison", -"equites", -"equity", -"equoid", -"er", -"era", -"erade", -"eral", -"eranist", -"erase", -"erased", -"eraser", -"erasion", -"erasure", -"erbia", -"erbium", -"erd", -"erdvark", -"ere", -"erect", -"erecter", -"erectly", -"erector", -"erelong", -"eremic", -"eremite", -"erenach", -"erenow", -"erepsin", -"erept", -"ereptic", -"erethic", -"erg", -"ergal", -"ergasia", -"ergates", -"ergodic", -"ergoism", -"ergon", -"ergot", -"ergoted", -"ergotic", -"ergotin", -"ergusia", -"eria", -"eric", -"ericad", -"erical", -"ericius", -"ericoid", -"erika", -"erikite", -"erineum", -"erinite", -"erinose", -"eristic", -"erizo", -"erlking", -"ermelin", -"ermine", -"ermined", -"erminee", -"ermines", -"erne", -"erode", -"eroded", -"erodent", -"erogeny", -"eros", -"erose", -"erosely", -"erosion", -"erosive", -"eroteme", -"erotic", -"erotica", -"erotism", -"err", -"errable", -"errancy", -"errand", -"errant", -"errata", -"erratic", -"erratum", -"errhine", -"erring", -"errite", -"error", -"ers", -"ersatz", -"erth", -"erthen", -"erthly", -"eruc", -"eruca", -"erucic", -"erucin", -"eruct", -"erudit", -"erudite", -"erugate", -"erupt", -"eryngo", -"es", -"esca", -"escalan", -"escalin", -"escalop", -"escape", -"escapee", -"escaper", -"escarp", -"eschar", -"eschara", -"escheat", -"eschew", -"escoba", -"escolar", -"escort", -"escribe", -"escrol", -"escrow", -"escudo", -"esculin", -"esere", -"eserine", -"esexual", -"eshin", -"esker", -"esne", -"esodic", -"esotery", -"espadon", -"esparto", -"espave", -"espial", -"espier", -"espinal", -"espino", -"esplees", -"espouse", -"espy", -"esquire", -"ess", -"essang", -"essay", -"essayer", -"essed", -"essence", -"essency", -"essling", -"essoin", -"estadal", -"estadio", -"estado", -"estamp", -"estate", -"esteem", -"ester", -"estevin", -"estival", -"estmark", -"estoc", -"estoile", -"estop", -"estrade", -"estray", -"estre", -"estreat", -"estrepe", -"estrin", -"estriol", -"estrone", -"estrous", -"estrual", -"estuary", -"estufa", -"estuous", -"estus", -"eta", -"etacism", -"etacist", -"etalon", -"etamine", -"etch", -"etcher", -"etching", -"eternal", -"etesian", -"ethal", -"ethanal", -"ethane", -"ethanol", -"ethel", -"ethene", -"ethenic", -"ethenol", -"ethenyl", -"ether", -"ethered", -"etheric", -"etherin", -"ethic", -"ethical", -"ethics", -"ethid", -"ethide", -"ethine", -"ethiops", -"ethmoid", -"ethnal", -"ethnic", -"ethnize", -"ethnos", -"ethos", -"ethoxyl", -"ethrog", -"ethyl", -"ethylic", -"ethylin", -"ethyne", -"ethynyl", -"etiolin", -"etna", -"ettle", -"etua", -"etude", -"etui", -"etym", -"etymic", -"etymon", -"etypic", -"eu", -"euaster", -"eucaine", -"euchre", -"euchred", -"euclase", -"eucone", -"euconic", -"eucrasy", -"eucrite", -"euge", -"eugenic", -"eugenol", -"eugeny", -"eulalia", -"eulogia", -"eulogic", -"eulogy", -"eumenid", -"eunicid", -"eunomy", -"eunuch", -"euonym", -"euonymy", -"euouae", -"eupad", -"eupathy", -"eupepsy", -"euphemy", -"euphon", -"euphone", -"euphony", -"euphory", -"euphroe", -"eupione", -"euploid", -"eupnea", -"eureka", -"euripus", -"eurite", -"eurobin", -"euryon", -"eusol", -"eustyle", -"eutaxic", -"eutaxy", -"eutexia", -"eutony", -"evacue", -"evacuee", -"evade", -"evader", -"evalue", -"evangel", -"evanish", -"evase", -"evasion", -"evasive", -"eve", -"evejar", -"evelong", -"even", -"evener", -"evening", -"evenly", -"evens", -"event", -"eveque", -"ever", -"evert", -"evertor", -"everwho", -"every", -"evestar", -"evetide", -"eveweed", -"evict", -"evictor", -"evident", -"evil", -"evilly", -"evince", -"evirate", -"evisite", -"evitate", -"evocate", -"evoe", -"evoke", -"evoker", -"evolute", -"evolve", -"evolver", -"evovae", -"evulse", -"evzone", -"ewder", -"ewe", -"ewer", -"ewerer", -"ewery", -"ewry", -"ex", -"exact", -"exacter", -"exactly", -"exactor", -"exalate", -"exalt", -"exalted", -"exalter", -"exam", -"examen", -"examine", -"example", -"exarate", -"exarch", -"exarchy", -"excamb", -"excave", -"exceed", -"excel", -"except", -"excerpt", -"excess", -"excide", -"exciple", -"excise", -"excisor", -"excite", -"excited", -"exciter", -"excitor", -"exclaim", -"exclave", -"exclude", -"excreta", -"excrete", -"excurse", -"excusal", -"excuse", -"excuser", -"excuss", -"excyst", -"exdie", -"exeat", -"execute", -"exedent", -"exedra", -"exegete", -"exempt", -"exequy", -"exergue", -"exert", -"exes", -"exeunt", -"exflect", -"exhale", -"exhaust", -"exhibit", -"exhort", -"exhume", -"exhumer", -"exigent", -"exile", -"exiler", -"exilian", -"exilic", -"exility", -"exist", -"exister", -"exit", -"exite", -"exition", -"exitus", -"exlex", -"exocarp", -"exocone", -"exode", -"exoderm", -"exodic", -"exodist", -"exodos", -"exodus", -"exody", -"exogamy", -"exogen", -"exogeny", -"exomion", -"exomis", -"exon", -"exoner", -"exopod", -"exordia", -"exormia", -"exosmic", -"exostra", -"exotic", -"exotism", -"expand", -"expanse", -"expect", -"expede", -"expel", -"expend", -"expense", -"expert", -"expiate", -"expire", -"expiree", -"expirer", -"expiry", -"explain", -"explant", -"explode", -"exploit", -"explore", -"expone", -"export", -"exposal", -"expose", -"exposed", -"exposer", -"exposit", -"expound", -"express", -"expugn", -"expulse", -"expunge", -"expurge", -"exradio", -"exscind", -"exsect", -"exsert", -"exship", -"exsurge", -"extant", -"extend", -"extense", -"extent", -"exter", -"extern", -"externe", -"extima", -"extinct", -"extine", -"extol", -"extoll", -"extort", -"extra", -"extract", -"extrait", -"extreme", -"extrude", -"extund", -"exudate", -"exude", -"exult", -"exultet", -"exuviae", -"exuvial", -"ey", -"eyah", -"eyalet", -"eyas", -"eye", -"eyeball", -"eyebalm", -"eyebar", -"eyebeam", -"eyebolt", -"eyebree", -"eyebrow", -"eyecup", -"eyed", -"eyedot", -"eyedrop", -"eyeflap", -"eyeful", -"eyehole", -"eyelash", -"eyeless", -"eyelet", -"eyelid", -"eyelike", -"eyeline", -"eyemark", -"eyen", -"eyepit", -"eyer", -"eyeroot", -"eyeseed", -"eyeshot", -"eyesome", -"eyesore", -"eyespot", -"eyewash", -"eyewear", -"eyewink", -"eyewort", -"eyey", -"eying", -"eyn", -"eyne", -"eyot", -"eyoty", -"eyra", -"eyre", -"eyrie", -"eyrir", -"ezba", -"f", -"fa", -"fabella", -"fabes", -"fable", -"fabled", -"fabler", -"fabliau", -"fabling", -"fabric", -"fabular", -"facadal", -"facade", -"face", -"faced", -"faceman", -"facer", -"facet", -"facete", -"faceted", -"facia", -"facial", -"faciend", -"facient", -"facies", -"facile", -"facing", -"fack", -"fackins", -"facks", -"fact", -"factful", -"faction", -"factish", -"factive", -"factor", -"factory", -"factrix", -"factual", -"factum", -"facture", -"facty", -"facula", -"facular", -"faculty", -"facund", -"facy", -"fad", -"fadable", -"faddish", -"faddism", -"faddist", -"faddle", -"faddy", -"fade", -"faded", -"fadedly", -"faden", -"fader", -"fadge", -"fading", -"fady", -"fae", -"faerie", -"faery", -"faff", -"faffle", -"faffy", -"fag", -"fagald", -"fage", -"fager", -"fagger", -"faggery", -"fagging", -"fagine", -"fagot", -"fagoter", -"fagoty", -"faham", -"fahlerz", -"fahlore", -"faience", -"fail", -"failing", -"faille", -"failure", -"fain", -"fainly", -"fains", -"faint", -"fainter", -"faintly", -"faints", -"fainty", -"faipule", -"fair", -"fairer", -"fairily", -"fairing", -"fairish", -"fairly", -"fairm", -"fairway", -"fairy", -"faith", -"faitour", -"fake", -"faker", -"fakery", -"fakir", -"faky", -"falbala", -"falcade", -"falcate", -"falcer", -"falces", -"falcial", -"falcon", -"falcula", -"faldage", -"faldfee", -"fall", -"fallace", -"fallacy", -"fallage", -"fallen", -"faller", -"falling", -"fallow", -"fallway", -"fally", -"falsary", -"false", -"falsely", -"falsen", -"falser", -"falsie", -"falsify", -"falsism", -"faltche", -"falter", -"falutin", -"falx", -"fam", -"famble", -"fame", -"fameful", -"familia", -"family", -"famine", -"famish", -"famous", -"famulus", -"fan", -"fana", -"fanal", -"fanam", -"fanatic", -"fanback", -"fancied", -"fancier", -"fancify", -"fancy", -"fand", -"fandom", -"fanega", -"fanfare", -"fanfoot", -"fang", -"fanged", -"fangle", -"fangled", -"fanglet", -"fangot", -"fangy", -"fanion", -"fanlike", -"fanman", -"fannel", -"fanner", -"fannier", -"fanning", -"fanon", -"fant", -"fantail", -"fantast", -"fantasy", -"fantod", -"fanweed", -"fanwise", -"fanwork", -"fanwort", -"faon", -"far", -"farad", -"faraday", -"faradic", -"faraway", -"farce", -"farcer", -"farcial", -"farcied", -"farcify", -"farcing", -"farcist", -"farcy", -"farde", -"fardel", -"fardh", -"fardo", -"fare", -"farer", -"farfara", -"farfel", -"fargood", -"farina", -"faring", -"farish", -"farl", -"farleu", -"farm", -"farmage", -"farmer", -"farmery", -"farming", -"farmost", -"farmy", -"farness", -"faro", -"farrago", -"farrand", -"farrier", -"farrow", -"farruca", -"farse", -"farseer", -"farset", -"farther", -"fasces", -"fascet", -"fascia", -"fascial", -"fascine", -"fascis", -"fascism", -"fascist", -"fash", -"fasher", -"fashery", -"fashion", -"fass", -"fast", -"fasten", -"faster", -"fasting", -"fastish", -"fastus", -"fat", -"fatal", -"fatally", -"fatbird", -"fate", -"fated", -"fateful", -"fathead", -"father", -"fathmur", -"fathom", -"fatidic", -"fatigue", -"fatiha", -"fatil", -"fatless", -"fatling", -"fatly", -"fatness", -"fatsia", -"fatten", -"fatter", -"fattily", -"fattish", -"fatty", -"fatuism", -"fatuity", -"fatuoid", -"fatuous", -"fatwood", -"faucal", -"fauces", -"faucet", -"faucial", -"faucre", -"faugh", -"fauld", -"fault", -"faulter", -"faulty", -"faun", -"faunal", -"faunish", -"faunist", -"faunule", -"fause", -"faust", -"fautor", -"fauve", -"favella", -"favilla", -"favism", -"favissa", -"favn", -"favor", -"favored", -"favorer", -"favose", -"favous", -"favus", -"fawn", -"fawner", -"fawnery", -"fawning", -"fawny", -"fay", -"fayles", -"faze", -"fazenda", -"fe", -"feague", -"feak", -"feal", -"fealty", -"fear", -"feared", -"fearer", -"fearful", -"feasor", -"feast", -"feasten", -"feaster", -"feat", -"feather", -"featly", -"featous", -"feature", -"featy", -"feaze", -"febrile", -"fecal", -"feces", -"feck", -"feckful", -"feckly", -"fecula", -"fecund", -"fed", -"feddan", -"federal", -"fee", -"feeable", -"feeble", -"feebly", -"feed", -"feedbin", -"feedbox", -"feeder", -"feeding", -"feedman", -"feedway", -"feedy", -"feel", -"feeler", -"feeless", -"feeling", -"feer", -"feere", -"feering", -"feetage", -"feeze", -"fegary", -"fei", -"feif", -"feigher", -"feign", -"feigned", -"feigner", -"feil", -"feint", -"feis", -"feist", -"feisty", -"felid", -"feline", -"fell", -"fellage", -"fellah", -"fellen", -"feller", -"fellic", -"felling", -"felloe", -"fellow", -"felly", -"feloid", -"felon", -"felonry", -"felony", -"fels", -"felsite", -"felt", -"felted", -"felter", -"felting", -"felty", -"felucca", -"felwort", -"female", -"feme", -"femic", -"feminal", -"feminie", -"feminin", -"femora", -"femoral", -"femur", -"fen", -"fenbank", -"fence", -"fencer", -"fenchyl", -"fencing", -"fend", -"fender", -"fendy", -"fenite", -"fenks", -"fenland", -"fenman", -"fennec", -"fennel", -"fennig", -"fennish", -"fenny", -"fensive", -"fent", -"fenter", -"feod", -"feodal", -"feodary", -"feoff", -"feoffee", -"feoffor", -"feower", -"feral", -"feralin", -"ferash", -"ferdwit", -"ferfet", -"feria", -"ferial", -"feridgi", -"ferie", -"ferine", -"ferity", -"ferk", -"ferling", -"ferly", -"fermail", -"ferme", -"ferment", -"fermery", -"fermila", -"fern", -"ferned", -"fernery", -"ferny", -"feroher", -"ferrado", -"ferrate", -"ferrean", -"ferret", -"ferrety", -"ferri", -"ferric", -"ferrier", -"ferrite", -"ferrous", -"ferrule", -"ferrum", -"ferry", -"fertile", -"feru", -"ferula", -"ferule", -"ferulic", -"fervent", -"fervid", -"fervor", -"fescue", -"fess", -"fessely", -"fest", -"festal", -"fester", -"festine", -"festive", -"festoon", -"festuca", -"fet", -"fetal", -"fetch", -"fetched", -"fetcher", -"fetial", -"fetid", -"fetidly", -"fetish", -"fetlock", -"fetlow", -"fetor", -"fetter", -"fettle", -"fettler", -"fetus", -"feu", -"feuage", -"feuar", -"feucht", -"feud", -"feudal", -"feudee", -"feudist", -"feued", -"feuille", -"fever", -"feveret", -"few", -"fewness", -"fewsome", -"fewter", -"fey", -"feyness", -"fez", -"fezzed", -"fezzy", -"fi", -"fiacre", -"fiance", -"fiancee", -"fiar", -"fiard", -"fiasco", -"fiat", -"fib", -"fibber", -"fibbery", -"fibdom", -"fiber", -"fibered", -"fibril", -"fibrin", -"fibrine", -"fibroid", -"fibroin", -"fibroma", -"fibrose", -"fibrous", -"fibry", -"fibster", -"fibula", -"fibulae", -"fibular", -"ficary", -"fice", -"ficelle", -"fiche", -"fichu", -"fickle", -"fickly", -"fico", -"ficoid", -"fictile", -"fiction", -"fictive", -"fid", -"fidalgo", -"fidate", -"fiddle", -"fiddler", -"fiddley", -"fide", -"fideism", -"fideist", -"fidfad", -"fidge", -"fidget", -"fidgety", -"fiducia", -"fie", -"fiefdom", -"field", -"fielded", -"fielder", -"fieldy", -"fiend", -"fiendly", -"fient", -"fierce", -"fiercen", -"fierily", -"fiery", -"fiesta", -"fife", -"fifer", -"fifie", -"fifish", -"fifo", -"fifteen", -"fifth", -"fifthly", -"fifty", -"fig", -"figaro", -"figbird", -"figent", -"figged", -"figgery", -"figging", -"figgle", -"figgy", -"fight", -"fighter", -"figless", -"figlike", -"figment", -"figural", -"figure", -"figured", -"figurer", -"figury", -"figworm", -"figwort", -"fike", -"fikie", -"filace", -"filacer", -"filao", -"filar", -"filaria", -"filasse", -"filate", -"filator", -"filbert", -"filch", -"filcher", -"file", -"filemot", -"filer", -"filet", -"filial", -"filiate", -"filibeg", -"filical", -"filicic", -"filicin", -"filiety", -"filing", -"filings", -"filippo", -"filite", -"fill", -"filled", -"filler", -"fillet", -"filleul", -"filling", -"fillip", -"fillock", -"filly", -"film", -"filmdom", -"filmet", -"filmic", -"filmily", -"filmish", -"filmist", -"filmize", -"filmy", -"filo", -"filose", -"fils", -"filter", -"filth", -"filthy", -"fimble", -"fimbria", -"fin", -"finable", -"finagle", -"final", -"finale", -"finally", -"finance", -"finback", -"finch", -"finched", -"find", -"findal", -"finder", -"finding", -"findjan", -"fine", -"fineish", -"finely", -"finer", -"finery", -"finesse", -"finetop", -"finfish", -"finfoot", -"fingent", -"finger", -"fingery", -"finial", -"finical", -"finick", -"finific", -"finify", -"finikin", -"fining", -"finis", -"finish", -"finite", -"finity", -"finjan", -"fink", -"finkel", -"finland", -"finless", -"finlet", -"finlike", -"finnac", -"finned", -"finner", -"finnip", -"finny", -"fiord", -"fiorded", -"fiorin", -"fiorite", -"fip", -"fipenny", -"fipple", -"fique", -"fir", -"firca", -"fire", -"firearm", -"firebox", -"fireboy", -"firebug", -"fired", -"firedog", -"firefly", -"firelit", -"fireman", -"firer", -"firetop", -"firing", -"firk", -"firker", -"firkin", -"firlot", -"firm", -"firman", -"firmer", -"firmly", -"firn", -"firring", -"firry", -"first", -"firstly", -"firth", -"fisc", -"fiscal", -"fise", -"fisetin", -"fish", -"fishbed", -"fished", -"fisher", -"fishery", -"fishet", -"fisheye", -"fishful", -"fishgig", -"fishify", -"fishily", -"fishing", -"fishlet", -"fishman", -"fishpot", -"fishway", -"fishy", -"fisnoga", -"fissate", -"fissile", -"fission", -"fissive", -"fissure", -"fissury", -"fist", -"fisted", -"fister", -"fistful", -"fistic", -"fistify", -"fisting", -"fistuca", -"fistula", -"fistule", -"fisty", -"fit", -"fitch", -"fitched", -"fitchee", -"fitcher", -"fitchet", -"fitchew", -"fitful", -"fitly", -"fitment", -"fitness", -"fitout", -"fitroot", -"fittage", -"fitted", -"fitten", -"fitter", -"fitters", -"fittily", -"fitting", -"fitty", -"fitweed", -"five", -"fivebar", -"fiver", -"fives", -"fix", -"fixable", -"fixage", -"fixate", -"fixatif", -"fixator", -"fixed", -"fixedly", -"fixer", -"fixing", -"fixity", -"fixture", -"fixure", -"fizgig", -"fizz", -"fizzer", -"fizzle", -"fizzy", -"fjeld", -"flabby", -"flabrum", -"flaccid", -"flack", -"flacked", -"flacker", -"flacket", -"flaff", -"flaffer", -"flag", -"flagger", -"flaggy", -"flaglet", -"flagman", -"flagon", -"flail", -"flair", -"flaith", -"flak", -"flakage", -"flake", -"flaker", -"flakily", -"flaky", -"flam", -"flamant", -"flamb", -"flame", -"flamed", -"flamen", -"flamer", -"flamfew", -"flaming", -"flamy", -"flan", -"flanch", -"flandan", -"flane", -"flange", -"flanger", -"flank", -"flanked", -"flanker", -"flanky", -"flannel", -"flanque", -"flap", -"flapper", -"flare", -"flaring", -"flary", -"flaser", -"flash", -"flasher", -"flashet", -"flashly", -"flashy", -"flask", -"flasker", -"flasket", -"flasque", -"flat", -"flatcap", -"flatcar", -"flatdom", -"flated", -"flathat", -"flatlet", -"flatly", -"flatman", -"flatten", -"flatter", -"flattie", -"flattop", -"flatus", -"flatway", -"flaught", -"flaunt", -"flaunty", -"flavedo", -"flavic", -"flavid", -"flavin", -"flavine", -"flavo", -"flavone", -"flavor", -"flavory", -"flavour", -"flaw", -"flawed", -"flawful", -"flawn", -"flawy", -"flax", -"flaxen", -"flaxman", -"flaxy", -"flay", -"flayer", -"flea", -"fleam", -"fleay", -"flebile", -"fleche", -"fleck", -"flecken", -"flecker", -"flecky", -"flector", -"fled", -"fledge", -"fledgy", -"flee", -"fleece", -"fleeced", -"fleecer", -"fleech", -"fleecy", -"fleer", -"fleerer", -"fleet", -"fleeter", -"fleetly", -"flemish", -"flench", -"flense", -"flenser", -"flerry", -"flesh", -"fleshed", -"fleshen", -"flesher", -"fleshly", -"fleshy", -"flet", -"fletch", -"flether", -"fleuret", -"fleury", -"flew", -"flewed", -"flewit", -"flews", -"flex", -"flexed", -"flexile", -"flexion", -"flexor", -"flexure", -"fley", -"flick", -"flicker", -"flicky", -"flidder", -"flier", -"fligger", -"flight", -"flighty", -"flimmer", -"flimp", -"flimsy", -"flinch", -"flinder", -"fling", -"flinger", -"flingy", -"flint", -"flinter", -"flinty", -"flioma", -"flip", -"flipe", -"flipper", -"flirt", -"flirter", -"flirty", -"flisk", -"flisky", -"flit", -"flitch", -"flite", -"fliting", -"flitter", -"flivver", -"flix", -"float", -"floater", -"floaty", -"flob", -"flobby", -"floc", -"floccus", -"flock", -"flocker", -"flocky", -"flocoon", -"flodge", -"floe", -"floey", -"flog", -"flogger", -"flokite", -"flong", -"flood", -"flooded", -"flooder", -"floody", -"floor", -"floorer", -"floozy", -"flop", -"flopper", -"floppy", -"flora", -"floral", -"floran", -"florate", -"floreal", -"florent", -"flores", -"floret", -"florid", -"florin", -"florist", -"floroon", -"florula", -"flory", -"flosh", -"floss", -"flosser", -"flossy", -"flot", -"flota", -"flotage", -"flotant", -"flotsam", -"flounce", -"flour", -"floury", -"flouse", -"flout", -"flouter", -"flow", -"flowage", -"flower", -"flowery", -"flowing", -"flown", -"flowoff", -"flu", -"fluate", -"fluavil", -"flub", -"flubdub", -"flucan", -"flue", -"flued", -"flueman", -"fluency", -"fluent", -"fluer", -"fluey", -"fluff", -"fluffer", -"fluffy", -"fluible", -"fluid", -"fluidal", -"fluidic", -"fluidly", -"fluke", -"fluked", -"flukily", -"fluking", -"fluky", -"flume", -"flummer", -"flummox", -"flump", -"flung", -"flunk", -"flunker", -"flunky", -"fluor", -"fluoran", -"fluoric", -"fluoryl", -"flurn", -"flurr", -"flurry", -"flush", -"flusher", -"flushy", -"flusk", -"flusker", -"fluster", -"flute", -"fluted", -"fluter", -"flutina", -"fluting", -"flutist", -"flutter", -"fluty", -"fluvial", -"flux", -"fluxer", -"fluxile", -"fluxion", -"fly", -"flyable", -"flyaway", -"flyback", -"flyball", -"flybane", -"flybelt", -"flyblow", -"flyboat", -"flyboy", -"flyer", -"flyflap", -"flying", -"flyleaf", -"flyless", -"flyman", -"flyness", -"flype", -"flytail", -"flytier", -"flytrap", -"flyway", -"flywort", -"foal", -"foaly", -"foam", -"foambow", -"foamer", -"foamily", -"foaming", -"foamy", -"fob", -"focal", -"focally", -"foci", -"focoids", -"focsle", -"focus", -"focuser", -"fod", -"fodda", -"fodder", -"foder", -"fodge", -"fodgel", -"fodient", -"foe", -"foehn", -"foeish", -"foeless", -"foelike", -"foeman", -"foeship", -"fog", -"fogbow", -"fogdog", -"fogdom", -"fogey", -"foggage", -"fogged", -"fogger", -"foggily", -"foggish", -"foggy", -"foghorn", -"fogle", -"fogless", -"fogman", -"fogo", -"fogon", -"fogou", -"fogram", -"fogus", -"fogy", -"fogydom", -"fogyish", -"fogyism", -"fohat", -"foible", -"foil", -"foiler", -"foiling", -"foining", -"foison", -"foist", -"foister", -"foisty", -"foiter", -"fold", -"foldage", -"folded", -"folden", -"folder", -"folding", -"foldure", -"foldy", -"fole", -"folia", -"foliage", -"folial", -"foliar", -"foliary", -"foliate", -"folie", -"folio", -"foliole", -"foliose", -"foliot", -"folious", -"folium", -"folk", -"folkmot", -"folksy", -"folkway", -"folky", -"folles", -"follis", -"follow", -"folly", -"foment", -"fomes", -"fomites", -"fondak", -"fondant", -"fondish", -"fondle", -"fondler", -"fondly", -"fondu", -"fondue", -"fonduk", -"fonly", -"fonnish", -"fono", -"fons", -"font", -"fontal", -"fonted", -"fontful", -"fontlet", -"foo", -"food", -"fooder", -"foodful", -"foody", -"fool", -"fooldom", -"foolery", -"fooless", -"fooling", -"foolish", -"fooner", -"fooster", -"foot", -"footage", -"footboy", -"footed", -"footer", -"footful", -"foothot", -"footing", -"footle", -"footler", -"footman", -"footpad", -"foots", -"footway", -"footy", -"foozle", -"foozler", -"fop", -"fopling", -"foppery", -"foppish", -"foppy", -"fopship", -"for", -"fora", -"forage", -"forager", -"foramen", -"forane", -"foray", -"forayer", -"forb", -"forbade", -"forbar", -"forbear", -"forbid", -"forbit", -"forbled", -"forblow", -"forbore", -"forbow", -"forby", -"force", -"forced", -"forceps", -"forcer", -"forche", -"forcing", -"ford", -"fordays", -"fording", -"fordo", -"fordone", -"fordy", -"fore", -"foreact", -"forearm", -"forebay", -"forecar", -"foreday", -"forefin", -"forefit", -"forego", -"foreign", -"forel", -"forelay", -"foreleg", -"foreman", -"forepad", -"forepaw", -"foreran", -"forerib", -"forerun", -"foresay", -"foresee", -"foreset", -"foresin", -"forest", -"foresty", -"foretop", -"foreuse", -"forever", -"forevow", -"forfar", -"forfare", -"forfars", -"forfeit", -"forfend", -"forge", -"forged", -"forger", -"forgery", -"forget", -"forgie", -"forging", -"forgive", -"forgo", -"forgoer", -"forgot", -"forgrow", -"forhoo", -"forhooy", -"forhow", -"forint", -"fork", -"forked", -"forker", -"forkful", -"forkman", -"forky", -"forleft", -"forlet", -"forlorn", -"form", -"formal", -"formant", -"format", -"formate", -"forme", -"formed", -"formee", -"formel", -"formene", -"former", -"formful", -"formic", -"formin", -"forming", -"formose", -"formula", -"formule", -"formy", -"formyl", -"fornent", -"fornix", -"forpet", -"forpine", -"forpit", -"forrad", -"forrard", -"forride", -"forrit", -"forrue", -"forsake", -"forset", -"forslow", -"fort", -"forte", -"forth", -"forthgo", -"forthy", -"forties", -"fortify", -"fortin", -"fortis", -"fortlet", -"fortune", -"forty", -"forum", -"forward", -"forwean", -"forwent", -"fosh", -"fosie", -"fossa", -"fossage", -"fossane", -"fosse", -"fossed", -"fossick", -"fossil", -"fossor", -"fossula", -"fossule", -"fostell", -"foster", -"fot", -"fotch", -"fother", -"fotmal", -"fotui", -"fou", -"foud", -"fouette", -"fougade", -"fought", -"foughty", -"foujdar", -"foul", -"foulage", -"foulard", -"fouler", -"fouling", -"foulish", -"foully", -"foumart", -"foun", -"found", -"founder", -"foundry", -"fount", -"four", -"fourble", -"fourche", -"fourer", -"fourre", -"fourth", -"foussa", -"foute", -"fouter", -"fouth", -"fovea", -"foveal", -"foveate", -"foveola", -"foveole", -"fow", -"fowk", -"fowl", -"fowler", -"fowlery", -"fowling", -"fox", -"foxbane", -"foxchop", -"foxer", -"foxery", -"foxfeet", -"foxfish", -"foxhole", -"foxily", -"foxing", -"foxish", -"foxlike", -"foxship", -"foxskin", -"foxtail", -"foxwood", -"foxy", -"foy", -"foyaite", -"foyboat", -"foyer", -"fozy", -"fra", -"frab", -"frabbit", -"frabous", -"fracas", -"frache", -"frack", -"fracted", -"frae", -"fraghan", -"fragile", -"fraid", -"fraik", -"frail", -"frailly", -"frailty", -"fraise", -"fraiser", -"frame", -"framea", -"framed", -"framer", -"framing", -"frammit", -"franc", -"franco", -"frank", -"franker", -"frankly", -"frantic", -"franzy", -"frap", -"frappe", -"frasco", -"frase", -"frasier", -"frass", -"frat", -"fratch", -"fratchy", -"frater", -"fratery", -"fratry", -"fraud", -"fraught", -"frawn", -"fraxin", -"fray", -"frayed", -"fraying", -"frayn", -"fraze", -"frazer", -"frazil", -"frazzle", -"freak", -"freaky", -"fream", -"freath", -"freck", -"frecken", -"frecket", -"freckle", -"freckly", -"free", -"freed", -"freedom", -"freeing", -"freeish", -"freely", -"freeman", -"freer", -"freet", -"freety", -"freeway", -"freeze", -"freezer", -"freight", -"freir", -"freit", -"freity", -"fremd", -"fremdly", -"frenal", -"frenate", -"frenum", -"frenzy", -"fresco", -"fresh", -"freshen", -"freshet", -"freshly", -"fresnel", -"fresno", -"fret", -"fretful", -"frett", -"frette", -"fretted", -"fretter", -"fretty", -"fretum", -"friable", -"friand", -"friar", -"friarly", -"friary", -"frib", -"fribble", -"fribby", -"fried", -"friend", -"frier", -"frieze", -"friezer", -"friezy", -"frig", -"frigate", -"friggle", -"fright", -"frighty", -"frigid", -"frijol", -"frike", -"frill", -"frilled", -"friller", -"frilly", -"frim", -"fringe", -"fringed", -"fringy", -"frisca", -"frisk", -"frisker", -"frisket", -"frisky", -"frison", -"frist", -"frisure", -"frit", -"frith", -"fritt", -"fritter", -"frivol", -"frixion", -"friz", -"frize", -"frizer", -"frizz", -"frizzer", -"frizzle", -"frizzly", -"frizzy", -"fro", -"frock", -"froe", -"frog", -"frogbit", -"frogeye", -"frogged", -"froggy", -"frogleg", -"froglet", -"frogman", -"froise", -"frolic", -"from", -"frond", -"fronded", -"front", -"frontad", -"frontal", -"fronted", -"fronter", -"froom", -"frore", -"frory", -"frosh", -"frost", -"frosted", -"froster", -"frosty", -"frot", -"froth", -"frother", -"frothy", -"frotton", -"frough", -"froughy", -"frounce", -"frow", -"froward", -"frower", -"frowl", -"frown", -"frowner", -"frowny", -"frowst", -"frowsty", -"frowy", -"frowze", -"frowzly", -"frowzy", -"froze", -"frozen", -"fructed", -"frugal", -"fruggan", -"fruit", -"fruited", -"fruiter", -"fruity", -"frump", -"frumple", -"frumpy", -"frush", -"frustum", -"frutify", -"fry", -"fryer", -"fu", -"fub", -"fubby", -"fubsy", -"fucate", -"fuchsin", -"fuci", -"fucoid", -"fucosan", -"fucose", -"fucous", -"fucus", -"fud", -"fuddle", -"fuddler", -"fuder", -"fudge", -"fudger", -"fudgy", -"fuel", -"fueler", -"fuerte", -"fuff", -"fuffy", -"fugal", -"fugally", -"fuggy", -"fugient", -"fugle", -"fugler", -"fugu", -"fugue", -"fuguist", -"fuidhir", -"fuji", -"fulcral", -"fulcrum", -"fulfill", -"fulgent", -"fulgid", -"fulgide", -"fulgor", -"fulham", -"fulk", -"full", -"fullam", -"fuller", -"fullery", -"fulling", -"fullish", -"fullom", -"fully", -"fulmar", -"fulmine", -"fulsome", -"fulth", -"fulvene", -"fulvid", -"fulvous", -"fulwa", -"fulyie", -"fulzie", -"fum", -"fumado", -"fumage", -"fumaric", -"fumaryl", -"fumble", -"fumbler", -"fume", -"fumer", -"fumet", -"fumette", -"fumily", -"fuming", -"fumose", -"fumous", -"fumy", -"fun", -"fund", -"fundal", -"funded", -"funder", -"fundi", -"fundic", -"funds", -"fundus", -"funeral", -"funest", -"fungal", -"fungate", -"fungi", -"fungian", -"fungic", -"fungin", -"fungo", -"fungoid", -"fungose", -"fungous", -"fungus", -"fungusy", -"funicle", -"funis", -"funk", -"funker", -"funky", -"funnel", -"funnily", -"funny", -"funori", -"funt", -"fur", -"fural", -"furan", -"furazan", -"furbish", -"furca", -"furcal", -"furcate", -"furcula", -"furdel", -"furfur", -"furiant", -"furied", -"furify", -"furil", -"furilic", -"furiosa", -"furioso", -"furious", -"furison", -"furl", -"furler", -"furless", -"furlong", -"furnace", -"furnage", -"furner", -"furnish", -"furoic", -"furoid", -"furoin", -"furole", -"furor", -"furore", -"furphy", -"furred", -"furrier", -"furrily", -"furring", -"furrow", -"furrowy", -"furry", -"further", -"furtive", -"fury", -"furyl", -"furze", -"furzed", -"furzery", -"furzy", -"fusain", -"fusate", -"fusc", -"fuscin", -"fuscous", -"fuse", -"fused", -"fusee", -"fusht", -"fusible", -"fusibly", -"fusil", -"fusilly", -"fusion", -"fusoid", -"fuss", -"fusser", -"fussify", -"fussily", -"fussock", -"fussy", -"fust", -"fustee", -"fustet", -"fustian", -"fustic", -"fustily", -"fustin", -"fustle", -"fusty", -"fusuma", -"fusure", -"fut", -"futchel", -"fute", -"futhorc", -"futile", -"futtock", -"futural", -"future", -"futuric", -"futwa", -"fuye", -"fuze", -"fuzz", -"fuzzily", -"fuzzy", -"fyke", -"fylfot", -"fyrd", -"g", -"ga", -"gab", -"gabbard", -"gabber", -"gabble", -"gabbler", -"gabbro", -"gabby", -"gabelle", -"gabgab", -"gabi", -"gabion", -"gable", -"gablet", -"gablock", -"gaby", -"gad", -"gadbee", -"gadbush", -"gadded", -"gadder", -"gaddi", -"gadding", -"gaddish", -"gade", -"gadfly", -"gadge", -"gadger", -"gadget", -"gadid", -"gadling", -"gadman", -"gadoid", -"gadroon", -"gadsman", -"gaduin", -"gadwall", -"gaen", -"gaet", -"gaff", -"gaffe", -"gaffer", -"gaffle", -"gag", -"gagate", -"gage", -"gagee", -"gageite", -"gager", -"gagger", -"gaggery", -"gaggle", -"gaggler", -"gagman", -"gagor", -"gagroot", -"gahnite", -"gaiassa", -"gaiety", -"gaily", -"gain", -"gainage", -"gaine", -"gainer", -"gainful", -"gaining", -"gainly", -"gains", -"gainsay", -"gainset", -"gainst", -"gair", -"gait", -"gaited", -"gaiter", -"gaiting", -"gaize", -"gaj", -"gal", -"gala", -"galah", -"galanas", -"galanga", -"galant", -"galany", -"galatea", -"galaxy", -"galban", -"gale", -"galea", -"galeage", -"galeate", -"galee", -"galeeny", -"galeid", -"galena", -"galenic", -"galeoid", -"galera", -"galerum", -"galerus", -"galet", -"galey", -"galgal", -"gali", -"galilee", -"galiot", -"galipot", -"gall", -"galla", -"gallah", -"gallant", -"gallate", -"galled", -"gallein", -"galleon", -"galler", -"gallery", -"gallet", -"galley", -"gallfly", -"gallic", -"galline", -"galling", -"gallium", -"gallnut", -"gallon", -"galloon", -"gallop", -"gallous", -"gallows", -"gally", -"galoot", -"galop", -"galore", -"galosh", -"galp", -"galt", -"galumph", -"galuth", -"galyac", -"galyak", -"gam", -"gamahe", -"gamasid", -"gamb", -"gamba", -"gambade", -"gambado", -"gambang", -"gambeer", -"gambet", -"gambia", -"gambier", -"gambist", -"gambit", -"gamble", -"gambler", -"gamboge", -"gambol", -"gambrel", -"game", -"gamebag", -"gameful", -"gamely", -"gamene", -"gametal", -"gamete", -"gametic", -"gamic", -"gamily", -"gamin", -"gaming", -"gamma", -"gammer", -"gammick", -"gammock", -"gammon", -"gammy", -"gamont", -"gamori", -"gamp", -"gamut", -"gamy", -"gan", -"ganam", -"ganch", -"gander", -"gandul", -"gandum", -"gane", -"ganef", -"gang", -"ganga", -"gangan", -"gangava", -"gangdom", -"gange", -"ganger", -"ganging", -"gangism", -"ganglia", -"gangly", -"gangman", -"gangrel", -"gangue", -"gangway", -"ganja", -"ganner", -"gannet", -"ganoid", -"ganoin", -"ganosis", -"gansel", -"gansey", -"gansy", -"gant", -"ganta", -"gantang", -"gantlet", -"ganton", -"gantry", -"gantsl", -"ganza", -"ganzie", -"gaol", -"gaoler", -"gap", -"gapa", -"gape", -"gaper", -"gapes", -"gaping", -"gapo", -"gappy", -"gapy", -"gar", -"gara", -"garad", -"garage", -"garance", -"garava", -"garawi", -"garb", -"garbage", -"garbel", -"garbell", -"garbill", -"garble", -"garbler", -"garboil", -"garbure", -"garce", -"gardant", -"gardeen", -"garden", -"gardeny", -"gardy", -"gare", -"gareh", -"garetta", -"garfish", -"garget", -"gargety", -"gargle", -"gargol", -"garial", -"gariba", -"garish", -"garland", -"garle", -"garlic", -"garment", -"garn", -"garnel", -"garner", -"garnet", -"garnets", -"garnett", -"garnetz", -"garnice", -"garniec", -"garnish", -"garoo", -"garrafa", -"garran", -"garret", -"garrot", -"garrote", -"garrupa", -"garse", -"garsil", -"garston", -"garten", -"garter", -"garth", -"garum", -"garvey", -"garvock", -"gas", -"gasbag", -"gaseity", -"gaseous", -"gash", -"gashes", -"gashful", -"gashly", -"gashy", -"gasify", -"gasket", -"gaskin", -"gasking", -"gaskins", -"gasless", -"gaslit", -"gaslock", -"gasman", -"gasp", -"gasper", -"gasping", -"gaspy", -"gasser", -"gassing", -"gassy", -"gast", -"gaster", -"gastral", -"gastric", -"gastrin", -"gat", -"gata", -"gatch", -"gate", -"gateado", -"gateage", -"gated", -"gateman", -"gater", -"gateway", -"gather", -"gating", -"gator", -"gatter", -"gau", -"gaub", -"gauby", -"gauche", -"gaud", -"gaudery", -"gaudful", -"gaudily", -"gaudy", -"gaufer", -"gauffer", -"gauffre", -"gaufre", -"gauge", -"gauger", -"gauging", -"gaulin", -"gault", -"gaulter", -"gaum", -"gaumish", -"gaumy", -"gaun", -"gaunt", -"gaunted", -"gauntly", -"gauntry", -"gaunty", -"gaup", -"gaupus", -"gaur", -"gaus", -"gauss", -"gauster", -"gaut", -"gauze", -"gauzily", -"gauzy", -"gavall", -"gave", -"gavel", -"gaveler", -"gavial", -"gavotte", -"gavyuti", -"gaw", -"gawby", -"gawcie", -"gawk", -"gawkily", -"gawkish", -"gawky", -"gawm", -"gawn", -"gawney", -"gawsie", -"gay", -"gayal", -"gayatri", -"gaybine", -"gaycat", -"gayish", -"gayment", -"gayness", -"gaysome", -"gayyou", -"gaz", -"gazabo", -"gaze", -"gazebo", -"gazee", -"gazel", -"gazelle", -"gazer", -"gazette", -"gazi", -"gazing", -"gazon", -"gazy", -"ge", -"geal", -"gean", -"gear", -"gearbox", -"geared", -"gearing", -"gearman", -"gearset", -"gease", -"geason", -"geat", -"gebang", -"gebanga", -"gebbie", -"gebur", -"geck", -"gecko", -"geckoid", -"ged", -"gedackt", -"gedder", -"gedeckt", -"gedrite", -"gee", -"geebong", -"geebung", -"geejee", -"geek", -"geelbec", -"geerah", -"geest", -"geet", -"geezer", -"gegg", -"geggee", -"gegger", -"geggery", -"gein", -"geira", -"geisha", -"geison", -"geitjie", -"gel", -"gelable", -"gelada", -"gelatin", -"geld", -"geldant", -"gelder", -"gelding", -"gelid", -"gelidly", -"gelilah", -"gell", -"gelly", -"gelong", -"gelose", -"gelosin", -"gelt", -"gem", -"gemauve", -"gemel", -"gemeled", -"gemless", -"gemlike", -"gemma", -"gemmae", -"gemmate", -"gemmer", -"gemmily", -"gemmoid", -"gemmula", -"gemmule", -"gemmy", -"gemot", -"gemsbok", -"gemul", -"gemuti", -"gemwork", -"gen", -"gena", -"genal", -"genapp", -"genarch", -"gender", -"gene", -"genear", -"geneat", -"geneki", -"genep", -"genera", -"general", -"generic", -"genesic", -"genesis", -"genet", -"genetic", -"geneva", -"genial", -"genian", -"genic", -"genie", -"genii", -"genin", -"genion", -"genip", -"genipa", -"genipap", -"genista", -"genital", -"genitor", -"genius", -"genizah", -"genoese", -"genom", -"genome", -"genomic", -"genos", -"genre", -"genro", -"gens", -"genson", -"gent", -"genteel", -"gentes", -"gentian", -"gentile", -"gentle", -"gently", -"gentman", -"gentry", -"genty", -"genu", -"genua", -"genual", -"genuine", -"genus", -"genys", -"geo", -"geobios", -"geodal", -"geode", -"geodesy", -"geodete", -"geodic", -"geodist", -"geoduck", -"geoform", -"geogeny", -"geogony", -"geoid", -"geoidal", -"geology", -"geomaly", -"geomant", -"geomyid", -"geonoma", -"geopony", -"georama", -"georgic", -"geosid", -"geoside", -"geotaxy", -"geotic", -"geoty", -"ger", -"gerah", -"geranic", -"geranyl", -"gerate", -"gerated", -"geratic", -"geraty", -"gerb", -"gerbe", -"gerbil", -"gercrow", -"gerefa", -"gerenda", -"gerent", -"gerenuk", -"gerim", -"gerip", -"germ", -"germal", -"german", -"germane", -"germen", -"germin", -"germina", -"germing", -"germon", -"germule", -"germy", -"gernitz", -"geront", -"geronto", -"gers", -"gersum", -"gerund", -"gerusia", -"gervao", -"gesith", -"gesning", -"gesso", -"gest", -"gestant", -"gestate", -"geste", -"gested", -"gesten", -"gestic", -"gestion", -"gesture", -"get", -"geta", -"getah", -"getaway", -"gether", -"getling", -"getter", -"getting", -"getup", -"geum", -"gewgaw", -"gewgawy", -"gey", -"geyan", -"geyser", -"gez", -"ghafir", -"ghaist", -"ghalva", -"gharial", -"gharnao", -"gharry", -"ghastly", -"ghat", -"ghatti", -"ghatwal", -"ghazi", -"ghazism", -"ghebeta", -"ghee", -"gheleem", -"gherkin", -"ghetti", -"ghetto", -"ghizite", -"ghoom", -"ghost", -"ghoster", -"ghostly", -"ghosty", -"ghoul", -"ghrush", -"ghurry", -"giant", -"giantly", -"giantry", -"giardia", -"giarra", -"giarre", -"gib", -"gibaro", -"gibbals", -"gibbed", -"gibber", -"gibbet", -"gibbles", -"gibbon", -"gibbose", -"gibbous", -"gibbus", -"gibby", -"gibe", -"gibel", -"giber", -"gibing", -"gibleh", -"giblet", -"giblets", -"gibus", -"gid", -"giddap", -"giddea", -"giddify", -"giddily", -"giddy", -"gidgee", -"gie", -"gied", -"gien", -"gif", -"gift", -"gifted", -"giftie", -"gig", -"gigback", -"gigeria", -"gigful", -"gigger", -"giggish", -"giggit", -"giggle", -"giggler", -"giggly", -"giglet", -"giglot", -"gigman", -"gignate", -"gigolo", -"gigot", -"gigsman", -"gigster", -"gigtree", -"gigunu", -"gilbert", -"gild", -"gilded", -"gilden", -"gilder", -"gilding", -"gilguy", -"gilia", -"gilim", -"gill", -"gilled", -"giller", -"gillie", -"gilling", -"gilly", -"gilo", -"gilpy", -"gilse", -"gilt", -"giltcup", -"gim", -"gimbal", -"gimble", -"gimel", -"gimlet", -"gimlety", -"gimmal", -"gimmer", -"gimmick", -"gimp", -"gimped", -"gimper", -"gimping", -"gin", -"ging", -"ginger", -"gingery", -"gingham", -"gingili", -"gingiva", -"gink", -"ginkgo", -"ginned", -"ginner", -"ginners", -"ginnery", -"ginney", -"ginning", -"ginnle", -"ginny", -"ginseng", -"ginward", -"gio", -"gip", -"gipon", -"gipper", -"gipser", -"gipsire", -"giraffe", -"girasol", -"girba", -"gird", -"girder", -"girding", -"girdle", -"girdler", -"girl", -"girleen", -"girlery", -"girlie", -"girling", -"girlish", -"girlism", -"girly", -"girn", -"girny", -"giro", -"girr", -"girse", -"girsh", -"girsle", -"girt", -"girth", -"gisarme", -"gish", -"gisla", -"gisler", -"gist", -"git", -"gitalin", -"gith", -"gitonin", -"gitoxin", -"gittern", -"gittith", -"give", -"given", -"giver", -"givey", -"giving", -"gizz", -"gizzard", -"gizzen", -"gizzern", -"glace", -"glaceed", -"glacial", -"glacier", -"glacis", -"glack", -"glad", -"gladden", -"gladdon", -"gladdy", -"glade", -"gladeye", -"gladful", -"gladify", -"gladii", -"gladius", -"gladly", -"glady", -"glaga", -"glaieul", -"glaik", -"glaiket", -"glair", -"glairy", -"glaive", -"glaived", -"glaked", -"glaky", -"glam", -"glamour", -"glance", -"glancer", -"gland", -"glandes", -"glans", -"glar", -"glare", -"glarily", -"glaring", -"glarry", -"glary", -"glashan", -"glass", -"glassen", -"glasser", -"glasses", -"glassie", -"glassy", -"glaucin", -"glaum", -"glaur", -"glaury", -"glaver", -"glaze", -"glazed", -"glazen", -"glazer", -"glazier", -"glazily", -"glazing", -"glazy", -"gleam", -"gleamy", -"glean", -"gleaner", -"gleary", -"gleba", -"glebal", -"glebe", -"glebous", -"glede", -"gledy", -"glee", -"gleed", -"gleeful", -"gleek", -"gleeman", -"gleet", -"gleety", -"gleg", -"glegly", -"glen", -"glenoid", -"glent", -"gleyde", -"glia", -"gliadin", -"glial", -"glib", -"glibly", -"glidder", -"glide", -"glider", -"gliding", -"gliff", -"glime", -"glimmer", -"glimpse", -"glink", -"glint", -"glioma", -"gliosa", -"gliosis", -"glirine", -"glisk", -"glisky", -"glisten", -"glister", -"glitter", -"gloam", -"gloat", -"gloater", -"global", -"globate", -"globe", -"globed", -"globin", -"globoid", -"globose", -"globous", -"globule", -"globy", -"glochid", -"glochis", -"gloea", -"gloeal", -"glom", -"glome", -"glommox", -"glomus", -"glonoin", -"gloom", -"gloomth", -"gloomy", -"glop", -"gloppen", -"glor", -"glore", -"glorify", -"glory", -"gloss", -"glossa", -"glossal", -"glossed", -"glosser", -"glossic", -"glossy", -"glost", -"glottal", -"glottic", -"glottid", -"glottis", -"glout", -"glove", -"glover", -"glovey", -"gloving", -"glow", -"glower", -"glowfly", -"glowing", -"gloy", -"gloze", -"glozing", -"glub", -"glucase", -"glucid", -"glucide", -"glucina", -"glucine", -"gluck", -"glucose", -"glue", -"glued", -"gluepot", -"gluer", -"gluey", -"glug", -"gluish", -"glum", -"gluma", -"glumal", -"glume", -"glumly", -"glummy", -"glumose", -"glump", -"glumpy", -"glunch", -"glusid", -"gluside", -"glut", -"glutch", -"gluteal", -"gluten", -"gluteus", -"glutin", -"glutoid", -"glutose", -"glutter", -"glutton", -"glycid", -"glycide", -"glycine", -"glycol", -"glycose", -"glycyl", -"glyoxal", -"glyoxim", -"glyoxyl", -"glyph", -"glyphic", -"glyptic", -"glyster", -"gnabble", -"gnar", -"gnarl", -"gnarled", -"gnarly", -"gnash", -"gnat", -"gnathal", -"gnathic", -"gnatter", -"gnatty", -"gnaw", -"gnawer", -"gnawing", -"gnawn", -"gneiss", -"gneissy", -"gnome", -"gnomed", -"gnomic", -"gnomide", -"gnomish", -"gnomist", -"gnomon", -"gnosis", -"gnostic", -"gnu", -"go", -"goa", -"goad", -"goaf", -"goal", -"goalage", -"goalee", -"goalie", -"goanna", -"goat", -"goatee", -"goateed", -"goatish", -"goatly", -"goaty", -"goave", -"gob", -"goback", -"goban", -"gobang", -"gobbe", -"gobber", -"gobbet", -"gobbin", -"gobbing", -"gobble", -"gobbler", -"gobby", -"gobelin", -"gobi", -"gobiid", -"gobioid", -"goblet", -"goblin", -"gobline", -"gobo", -"gobony", -"goburra", -"goby", -"gocart", -"god", -"goddard", -"godded", -"goddess", -"goddize", -"gode", -"godet", -"godhead", -"godhood", -"godkin", -"godless", -"godlet", -"godlike", -"godlily", -"godling", -"godly", -"godown", -"godpapa", -"godsend", -"godship", -"godson", -"godwit", -"goeduck", -"goel", -"goelism", -"goer", -"goes", -"goetia", -"goetic", -"goety", -"goff", -"goffer", -"goffle", -"gog", -"gogga", -"goggan", -"goggle", -"goggled", -"goggler", -"goggly", -"goglet", -"gogo", -"goi", -"going", -"goitcho", -"goiter", -"goitral", -"gol", -"gola", -"golach", -"goladar", -"gold", -"goldbug", -"goldcup", -"golden", -"golder", -"goldie", -"goldin", -"goldish", -"goldtit", -"goldy", -"golee", -"golem", -"golf", -"golfdom", -"golfer", -"goli", -"goliard", -"goliath", -"golland", -"gollar", -"golly", -"goloe", -"golpe", -"gomari", -"gomart", -"gomavel", -"gombay", -"gombeen", -"gomer", -"gomeral", -"gomlah", -"gomuti", -"gon", -"gonad", -"gonadal", -"gonadic", -"gonagra", -"gonakie", -"gonal", -"gonapod", -"gondang", -"gondite", -"gondola", -"gone", -"goner", -"gong", -"gongman", -"gonia", -"goniac", -"gonial", -"goniale", -"gonid", -"gonidia", -"gonidic", -"gonimic", -"gonion", -"gonitis", -"gonium", -"gonne", -"gony", -"gonys", -"goo", -"goober", -"good", -"gooding", -"goodish", -"goodly", -"goodman", -"goods", -"goody", -"goof", -"goofer", -"goofily", -"goofy", -"googly", -"googol", -"googul", -"gook", -"gool", -"goolah", -"gools", -"gooma", -"goon", -"goondie", -"goonie", -"goose", -"goosery", -"goosish", -"goosy", -"gopher", -"gopura", -"gor", -"gora", -"goracco", -"goral", -"goran", -"gorb", -"gorbal", -"gorbet", -"gorble", -"gorce", -"gorcock", -"gorcrow", -"gore", -"gorer", -"gorevan", -"gorfly", -"gorge", -"gorged", -"gorger", -"gorget", -"gorglin", -"gorhen", -"goric", -"gorilla", -"gorily", -"goring", -"gorlin", -"gorlois", -"gormaw", -"gormed", -"gorra", -"gorraf", -"gorry", -"gorse", -"gorsedd", -"gorsy", -"gory", -"gos", -"gosain", -"goschen", -"gosh", -"goshawk", -"goslet", -"gosling", -"gosmore", -"gospel", -"gosport", -"gossan", -"gossard", -"gossip", -"gossipy", -"gossoon", -"gossy", -"got", -"gotch", -"gote", -"gothite", -"gotra", -"gotraja", -"gotten", -"gouaree", -"gouge", -"gouger", -"goujon", -"goulash", -"goumi", -"goup", -"gourami", -"gourd", -"gourde", -"gourdy", -"gourmet", -"gousty", -"gout", -"goutify", -"goutily", -"goutish", -"goutte", -"gouty", -"gove", -"govern", -"gowan", -"gowdnie", -"gowf", -"gowfer", -"gowk", -"gowked", -"gowkit", -"gowl", -"gown", -"gownlet", -"gowpen", -"goy", -"goyim", -"goyin", -"goyle", -"gozell", -"gozzard", -"gra", -"grab", -"grabber", -"grabble", -"graben", -"grace", -"gracer", -"gracile", -"grackle", -"grad", -"gradal", -"gradate", -"graddan", -"grade", -"graded", -"gradely", -"grader", -"gradin", -"gradine", -"grading", -"gradual", -"gradus", -"graff", -"graffer", -"graft", -"grafted", -"grafter", -"graham", -"grail", -"grailer", -"grain", -"grained", -"grainer", -"grainy", -"graip", -"graisse", -"graith", -"grallic", -"gram", -"grama", -"grame", -"grammar", -"gramme", -"gramp", -"grampa", -"grampus", -"granada", -"granage", -"granary", -"granate", -"granch", -"grand", -"grandam", -"grandee", -"grandly", -"grandma", -"grandpa", -"grane", -"grange", -"granger", -"granite", -"grank", -"grannom", -"granny", -"grano", -"granose", -"grant", -"grantee", -"granter", -"grantor", -"granula", -"granule", -"granza", -"grape", -"graped", -"grapery", -"graph", -"graphic", -"graphy", -"graping", -"grapnel", -"grappa", -"grapple", -"grapy", -"grasp", -"grasper", -"grass", -"grassed", -"grasser", -"grasset", -"grassy", -"grat", -"grate", -"grater", -"grather", -"gratify", -"grating", -"gratis", -"gratten", -"graupel", -"grave", -"graved", -"gravel", -"gravely", -"graven", -"graver", -"gravic", -"gravid", -"graving", -"gravity", -"gravure", -"gravy", -"grawls", -"gray", -"grayfly", -"grayish", -"graylag", -"grayly", -"graze", -"grazer", -"grazier", -"grazing", -"grease", -"greaser", -"greasy", -"great", -"greaten", -"greater", -"greatly", -"greave", -"greaved", -"greaves", -"grebe", -"grece", -"gree", -"greed", -"greedy", -"green", -"greener", -"greeney", -"greenly", -"greenth", -"greenuk", -"greeny", -"greet", -"greeter", -"gregal", -"gregale", -"grege", -"greggle", -"grego", -"greige", -"grein", -"greisen", -"gremial", -"gremlin", -"grenade", -"greund", -"grew", -"grey", -"greyly", -"gribble", -"grice", -"grid", -"griddle", -"gride", -"griece", -"grieced", -"grief", -"grieve", -"grieved", -"griever", -"griff", -"griffe", -"griffin", -"griffon", -"grift", -"grifter", -"grig", -"grignet", -"grigri", -"grike", -"grill", -"grille", -"grilled", -"griller", -"grilse", -"grim", -"grimace", -"grime", -"grimful", -"grimily", -"grimly", -"grimme", -"grimp", -"grimy", -"grin", -"grinch", -"grind", -"grinder", -"grindle", -"gringo", -"grinner", -"grinny", -"grip", -"gripe", -"griper", -"griping", -"gripman", -"grippal", -"grippe", -"gripper", -"gripple", -"grippy", -"gripy", -"gris", -"grisard", -"griskin", -"grisly", -"grison", -"grist", -"grister", -"gristle", -"gristly", -"gristy", -"grit", -"grith", -"grits", -"gritten", -"gritter", -"grittle", -"gritty", -"grivet", -"grivna", -"grizzle", -"grizzly", -"groan", -"groaner", -"groat", -"groats", -"grobian", -"grocer", -"grocery", -"groff", -"grog", -"groggy", -"grogram", -"groin", -"groined", -"grommet", -"groom", -"groomer", -"groomy", -"groop", -"groose", -"groot", -"grooty", -"groove", -"groover", -"groovy", -"grope", -"groper", -"groping", -"gropple", -"gros", -"groser", -"groset", -"gross", -"grossen", -"grosser", -"grossly", -"grosso", -"grosz", -"groszy", -"grot", -"grotto", -"grouch", -"grouchy", -"grouf", -"grough", -"ground", -"grounds", -"groundy", -"group", -"grouped", -"grouper", -"grouse", -"grouser", -"grousy", -"grout", -"grouter", -"grouts", -"grouty", -"grouze", -"grove", -"groved", -"grovel", -"grovy", -"grow", -"growan", -"growed", -"grower", -"growing", -"growl", -"growler", -"growly", -"grown", -"grownup", -"growse", -"growth", -"growthy", -"grozart", -"grozet", -"grr", -"grub", -"grubbed", -"grubber", -"grubby", -"grubs", -"grudge", -"grudger", -"grue", -"gruel", -"grueler", -"gruelly", -"gruff", -"gruffly", -"gruffs", -"gruffy", -"grufted", -"grugru", -"gruine", -"grum", -"grumble", -"grumbly", -"grume", -"grumly", -"grummel", -"grummet", -"grumose", -"grumous", -"grump", -"grumph", -"grumphy", -"grumpy", -"grun", -"grundy", -"grunion", -"grunt", -"grunter", -"gruntle", -"grush", -"grushie", -"gruss", -"grutch", -"grutten", -"gryde", -"grylli", -"gryllid", -"gryllos", -"gryllus", -"grysbok", -"guaba", -"guacimo", -"guacin", -"guaco", -"guaiac", -"guaiol", -"guaka", -"guama", -"guan", -"guana", -"guanaco", -"guanase", -"guanay", -"guango", -"guanine", -"guanize", -"guano", -"guanyl", -"guao", -"guapena", -"guar", -"guara", -"guarabu", -"guarana", -"guarani", -"guard", -"guarded", -"guarder", -"guardo", -"guariba", -"guarri", -"guasa", -"guava", -"guavina", -"guayaba", -"guayabi", -"guayabo", -"guayule", -"guaza", -"gubbo", -"gucki", -"gud", -"gudame", -"guddle", -"gude", -"gudge", -"gudgeon", -"gudget", -"gudok", -"gue", -"guebucu", -"guemal", -"guenepe", -"guenon", -"guepard", -"guerdon", -"guereza", -"guess", -"guesser", -"guest", -"guesten", -"guester", -"gufa", -"guff", -"guffaw", -"guffer", -"guffin", -"guffy", -"gugal", -"guggle", -"gugglet", -"guglet", -"guglia", -"guglio", -"gugu", -"guhr", -"guib", -"guiba", -"guidage", -"guide", -"guider", -"guidman", -"guidon", -"guige", -"guignol", -"guijo", -"guild", -"guilder", -"guildic", -"guildry", -"guile", -"guilery", -"guilt", -"guilty", -"guily", -"guimpe", -"guinea", -"guipure", -"guisard", -"guise", -"guiser", -"guising", -"guitar", -"gul", -"gula", -"gulae", -"gulaman", -"gular", -"gularis", -"gulch", -"gulden", -"gule", -"gules", -"gulf", -"gulfy", -"gulgul", -"gulix", -"gull", -"gullery", -"gullet", -"gullion", -"gullish", -"gully", -"gulonic", -"gulose", -"gulp", -"gulper", -"gulpin", -"gulping", -"gulpy", -"gulsach", -"gum", -"gumbo", -"gumboil", -"gumby", -"gumdrop", -"gumihan", -"gumless", -"gumlike", -"gumly", -"gumma", -"gummage", -"gummata", -"gummed", -"gummer", -"gumming", -"gummite", -"gummose", -"gummous", -"gummy", -"gump", -"gumpus", -"gumshoe", -"gumweed", -"gumwood", -"gun", -"guna", -"gunate", -"gunboat", -"gundi", -"gundy", -"gunebo", -"gunfire", -"gunge", -"gunite", -"gunj", -"gunk", -"gunl", -"gunless", -"gunlock", -"gunman", -"gunnage", -"gunne", -"gunnel", -"gunner", -"gunnery", -"gunnies", -"gunning", -"gunnung", -"gunny", -"gunong", -"gunplay", -"gunrack", -"gunsel", -"gunshop", -"gunshot", -"gunsman", -"gunster", -"gunter", -"gunwale", -"gunyah", -"gunyang", -"gunyeh", -"gup", -"guppy", -"gur", -"gurdle", -"gurge", -"gurgeon", -"gurges", -"gurgle", -"gurglet", -"gurgly", -"gurjun", -"gurk", -"gurl", -"gurly", -"gurnard", -"gurnet", -"gurniad", -"gurr", -"gurrah", -"gurry", -"gurt", -"guru", -"gush", -"gusher", -"gushet", -"gushily", -"gushing", -"gushy", -"gusla", -"gusle", -"guss", -"gusset", -"gussie", -"gust", -"gustful", -"gustily", -"gusto", -"gusty", -"gut", -"gutless", -"gutlike", -"gutling", -"gutt", -"gutta", -"guttate", -"gutte", -"gutter", -"guttery", -"gutti", -"guttide", -"guttie", -"guttle", -"guttler", -"guttula", -"guttule", -"guttus", -"gutty", -"gutweed", -"gutwise", -"gutwort", -"guy", -"guydom", -"guyer", -"guz", -"guze", -"guzzle", -"guzzler", -"gwag", -"gweduc", -"gweed", -"gweeon", -"gwely", -"gwine", -"gwyniad", -"gyle", -"gym", -"gymel", -"gymnast", -"gymnic", -"gymnics", -"gymnite", -"gymnure", -"gympie", -"gyn", -"gyne", -"gynecic", -"gynic", -"gynics", -"gyp", -"gype", -"gypper", -"gyps", -"gypsine", -"gypsite", -"gypsous", -"gypster", -"gypsum", -"gypsy", -"gypsyfy", -"gypsyry", -"gyral", -"gyrally", -"gyrant", -"gyrate", -"gyrator", -"gyre", -"gyrene", -"gyri", -"gyric", -"gyrinid", -"gyro", -"gyrocar", -"gyroma", -"gyron", -"gyronny", -"gyrose", -"gyrous", -"gyrus", -"gyte", -"gytling", -"gyve", -"h", -"ha", -"haab", -"haaf", -"habble", -"habeas", -"habena", -"habenal", -"habenar", -"habile", -"habille", -"habit", -"habitan", -"habitat", -"habited", -"habitue", -"habitus", -"habnab", -"haboob", -"habu", -"habutai", -"hache", -"hachure", -"hack", -"hackbut", -"hacked", -"hackee", -"hacker", -"hackery", -"hackin", -"hacking", -"hackle", -"hackler", -"hacklog", -"hackly", -"hackman", -"hackney", -"hacksaw", -"hacky", -"had", -"hadbot", -"hadden", -"haddie", -"haddo", -"haddock", -"hade", -"hading", -"hadj", -"hadji", -"hadland", -"hadrome", -"haec", -"haem", -"haemony", -"haet", -"haff", -"haffet", -"haffle", -"hafiz", -"hafnium", -"hafnyl", -"haft", -"hafter", -"hag", -"hagboat", -"hagborn", -"hagbush", -"hagdon", -"hageen", -"hagfish", -"haggada", -"haggard", -"hagged", -"hagger", -"haggis", -"haggish", -"haggle", -"haggler", -"haggly", -"haggy", -"hagi", -"hagia", -"haglet", -"haglike", -"haglin", -"hagride", -"hagrope", -"hagseed", -"hagship", -"hagweed", -"hagworm", -"hah", -"haik", -"haikai", -"haikal", -"haikwan", -"hail", -"hailer", -"hailse", -"haily", -"hain", -"haine", -"hair", -"haircut", -"hairdo", -"haire", -"haired", -"hairen", -"hairif", -"hairlet", -"hairpin", -"hairup", -"hairy", -"haje", -"hajib", -"hajilij", -"hak", -"hakam", -"hakdar", -"hake", -"hakeem", -"hakim", -"hako", -"haku", -"hala", -"halakah", -"halakic", -"halal", -"halberd", -"halbert", -"halch", -"halcyon", -"hale", -"halebi", -"haler", -"halerz", -"half", -"halfer", -"halfman", -"halfway", -"halibiu", -"halibut", -"halide", -"halidom", -"halite", -"halitus", -"hall", -"hallage", -"hallah", -"hallan", -"hallel", -"hallex", -"halling", -"hallman", -"halloo", -"hallow", -"hallux", -"hallway", -"halma", -"halo", -"halogen", -"haloid", -"hals", -"halse", -"halsen", -"halt", -"halter", -"halting", -"halurgy", -"halutz", -"halvans", -"halve", -"halved", -"halver", -"halves", -"halyard", -"ham", -"hamal", -"hamald", -"hamate", -"hamated", -"hamatum", -"hamble", -"hame", -"hameil", -"hamel", -"hamfat", -"hami", -"hamlah", -"hamlet", -"hammada", -"hammam", -"hammer", -"hammock", -"hammy", -"hamose", -"hamous", -"hamper", -"hamsa", -"hamster", -"hamular", -"hamule", -"hamulus", -"hamus", -"hamza", -"han", -"hanaper", -"hanbury", -"hance", -"hanced", -"hanch", -"hand", -"handbag", -"handbow", -"handcar", -"handed", -"hander", -"handful", -"handgun", -"handily", -"handle", -"handled", -"handler", -"handout", -"handsaw", -"handsel", -"handset", -"handy", -"hangar", -"hangby", -"hangdog", -"hange", -"hangee", -"hanger", -"hangie", -"hanging", -"hangle", -"hangman", -"hangout", -"hangul", -"hanif", -"hank", -"hanker", -"hankie", -"hankle", -"hanky", -"hanna", -"hansa", -"hanse", -"hansel", -"hansom", -"hant", -"hantle", -"hao", -"haole", -"haoma", -"haori", -"hap", -"hapless", -"haplite", -"haploid", -"haploma", -"haplont", -"haply", -"happen", -"happier", -"happify", -"happily", -"happing", -"happy", -"hapten", -"haptene", -"haptere", -"haptic", -"haptics", -"hapu", -"hapuku", -"harass", -"haratch", -"harbi", -"harbor", -"hard", -"harden", -"harder", -"hardily", -"hardim", -"hardish", -"hardly", -"hardock", -"hardpan", -"hardy", -"hare", -"harebur", -"harelip", -"harem", -"harfang", -"haricot", -"harish", -"hark", -"harka", -"harl", -"harling", -"harlock", -"harlot", -"harm", -"harmal", -"harmala", -"harman", -"harmel", -"harmer", -"harmful", -"harmine", -"harmony", -"harmost", -"harn", -"harness", -"harnpan", -"harp", -"harpago", -"harper", -"harpier", -"harpist", -"harpoon", -"harpula", -"harr", -"harrier", -"harrow", -"harry", -"harsh", -"harshen", -"harshly", -"hart", -"hartal", -"hartin", -"hartite", -"harvest", -"hasan", -"hash", -"hashab", -"hasher", -"hashish", -"hashy", -"hask", -"hasky", -"haslet", -"haslock", -"hasp", -"hassar", -"hassel", -"hassle", -"hassock", -"hasta", -"hastate", -"hastati", -"haste", -"hasten", -"haster", -"hastily", -"hastish", -"hastler", -"hasty", -"hat", -"hatable", -"hatband", -"hatbox", -"hatbrim", -"hatch", -"hatchel", -"hatcher", -"hatchet", -"hate", -"hateful", -"hater", -"hatful", -"hath", -"hathi", -"hatless", -"hatlike", -"hatpin", -"hatrack", -"hatrail", -"hatred", -"hatress", -"hatt", -"hatted", -"hatter", -"hattery", -"hatting", -"hattock", -"hatty", -"hau", -"hauberk", -"haugh", -"haught", -"haughty", -"haul", -"haulage", -"hauld", -"hauler", -"haulier", -"haulm", -"haulmy", -"haunch", -"haunchy", -"haunt", -"haunter", -"haunty", -"hause", -"hausen", -"hausse", -"hautboy", -"hauteur", -"havage", -"have", -"haveage", -"havel", -"haven", -"havener", -"havenet", -"havent", -"haver", -"haverel", -"haverer", -"havers", -"havier", -"havoc", -"haw", -"hawbuck", -"hawer", -"hawk", -"hawkbit", -"hawked", -"hawker", -"hawkery", -"hawkie", -"hawking", -"hawkish", -"hawknut", -"hawky", -"hawm", -"hawok", -"hawse", -"hawser", -"hay", -"haya", -"hayband", -"haybird", -"haybote", -"haycap", -"haycart", -"haycock", -"hayey", -"hayfork", -"haylift", -"hayloft", -"haymow", -"hayrack", -"hayrake", -"hayrick", -"hayseed", -"haysel", -"haysuck", -"haytime", -"hayward", -"hayweed", -"haywire", -"hayz", -"hazard", -"haze", -"hazel", -"hazeled", -"hazelly", -"hazen", -"hazer", -"hazily", -"hazing", -"hazle", -"hazy", -"hazzan", -"he", -"head", -"headcap", -"headed", -"header", -"headful", -"headily", -"heading", -"headman", -"headset", -"headway", -"heady", -"heaf", -"heal", -"heald", -"healder", -"healer", -"healful", -"healing", -"health", -"healthy", -"heap", -"heaper", -"heaps", -"heapy", -"hear", -"hearer", -"hearing", -"hearken", -"hearsay", -"hearse", -"hearst", -"heart", -"hearted", -"hearten", -"hearth", -"heartly", -"hearts", -"hearty", -"heat", -"heater", -"heatful", -"heath", -"heathen", -"heather", -"heathy", -"heating", -"heaume", -"heaumer", -"heave", -"heaven", -"heavens", -"heaver", -"heavies", -"heavily", -"heaving", -"heavity", -"heavy", -"hebamic", -"hebenon", -"hebete", -"hebetic", -"hech", -"heck", -"heckle", -"heckler", -"hectare", -"hecte", -"hectic", -"hector", -"heddle", -"heddler", -"hedebo", -"heder", -"hederic", -"hederin", -"hedge", -"hedger", -"hedging", -"hedgy", -"hedonic", -"heed", -"heeder", -"heedful", -"heedily", -"heedy", -"heehaw", -"heel", -"heelcap", -"heeled", -"heeler", -"heeltap", -"heer", -"heeze", -"heezie", -"heezy", -"heft", -"hefter", -"heftily", -"hefty", -"hegari", -"hegemon", -"hegira", -"hegumen", -"hei", -"heiau", -"heifer", -"heigh", -"height", -"heii", -"heimin", -"heinous", -"heir", -"heirdom", -"heiress", -"heitiki", -"hekteus", -"helbeh", -"helcoid", -"helder", -"hele", -"helenin", -"heliast", -"helical", -"heliced", -"helices", -"helicin", -"helicon", -"helide", -"heling", -"helio", -"helioid", -"helium", -"helix", -"hell", -"hellbox", -"hellcat", -"helldog", -"heller", -"helleri", -"hellhag", -"hellier", -"hellion", -"hellish", -"hello", -"helluo", -"helly", -"helm", -"helmage", -"helmed", -"helmet", -"helodes", -"heloe", -"heloma", -"helonin", -"helosis", -"helotry", -"help", -"helper", -"helpful", -"helping", -"helply", -"helve", -"helvell", -"helver", -"helvite", -"hem", -"hemad", -"hemal", -"hemapod", -"hemase", -"hematal", -"hematic", -"hematid", -"hematin", -"heme", -"hemen", -"hemera", -"hemiamb", -"hemic", -"hemin", -"hemina", -"hemine", -"heminee", -"hemiope", -"hemipic", -"heml", -"hemlock", -"hemmel", -"hemmer", -"hemocry", -"hemoid", -"hemol", -"hemopod", -"hemp", -"hempen", -"hempy", -"hen", -"henad", -"henbane", -"henbill", -"henbit", -"hence", -"hencoop", -"hencote", -"hend", -"hendly", -"henfish", -"henism", -"henlike", -"henna", -"hennery", -"hennin", -"hennish", -"henny", -"henotic", -"henpeck", -"henpen", -"henry", -"hent", -"henter", -"henware", -"henwife", -"henwise", -"henyard", -"hep", -"hepar", -"heparin", -"hepatic", -"hepcat", -"heppen", -"hepper", -"heptace", -"heptad", -"heptal", -"heptane", -"heptene", -"heptine", -"heptite", -"heptoic", -"heptose", -"heptyl", -"heptyne", -"her", -"herald", -"herb", -"herbage", -"herbal", -"herbane", -"herbary", -"herbish", -"herbist", -"herblet", -"herbman", -"herbose", -"herbous", -"herby", -"herd", -"herdboy", -"herder", -"herdic", -"herding", -"here", -"hereat", -"hereby", -"herein", -"herem", -"hereof", -"hereon", -"heresy", -"heretic", -"hereto", -"herile", -"heriot", -"heritor", -"herl", -"herling", -"herma", -"hermaic", -"hermit", -"hern", -"hernani", -"hernant", -"herne", -"hernia", -"hernial", -"hero", -"heroess", -"heroic", -"heroid", -"heroify", -"heroin", -"heroine", -"heroism", -"heroize", -"heron", -"heroner", -"heronry", -"herpes", -"herring", -"hers", -"herse", -"hersed", -"herself", -"hership", -"hersir", -"hertz", -"hessite", -"hest", -"hestern", -"het", -"hetaera", -"hetaery", -"heteric", -"hetero", -"hething", -"hetman", -"hetter", -"heuau", -"heugh", -"heumite", -"hevi", -"hew", -"hewable", -"hewel", -"hewer", -"hewhall", -"hewn", -"hewt", -"hex", -"hexa", -"hexace", -"hexacid", -"hexact", -"hexad", -"hexadic", -"hexagon", -"hexagyn", -"hexane", -"hexaped", -"hexapla", -"hexapod", -"hexarch", -"hexene", -"hexer", -"hexerei", -"hexeris", -"hexine", -"hexis", -"hexitol", -"hexode", -"hexogen", -"hexoic", -"hexone", -"hexonic", -"hexosan", -"hexose", -"hexyl", -"hexylic", -"hexyne", -"hey", -"heyday", -"hi", -"hia", -"hiant", -"hiatal", -"hiate", -"hiation", -"hiatus", -"hibbin", -"hic", -"hicatee", -"hiccup", -"hick", -"hickey", -"hickory", -"hidable", -"hidage", -"hidalgo", -"hidated", -"hidden", -"hide", -"hided", -"hideous", -"hider", -"hidling", -"hie", -"hieder", -"hield", -"hiemal", -"hieron", -"hieros", -"higdon", -"higgle", -"higgler", -"high", -"highboy", -"higher", -"highest", -"highish", -"highly", -"highman", -"hight", -"hightop", -"highway", -"higuero", -"hijack", -"hike", -"hiker", -"hilch", -"hilding", -"hill", -"hiller", -"hillet", -"hillman", -"hillock", -"hilltop", -"hilly", -"hilsa", -"hilt", -"hilum", -"hilus", -"him", -"himp", -"himself", -"himward", -"hin", -"hinau", -"hinch", -"hind", -"hinder", -"hing", -"hinge", -"hinger", -"hingle", -"hinney", -"hinny", -"hinoid", -"hinoki", -"hint", -"hinter", -"hiodont", -"hip", -"hipbone", -"hipe", -"hiper", -"hiphalt", -"hipless", -"hipmold", -"hipped", -"hippen", -"hippian", -"hippic", -"hipping", -"hippish", -"hipple", -"hippo", -"hippoid", -"hippus", -"hippy", -"hipshot", -"hipwort", -"hirable", -"hircine", -"hire", -"hired", -"hireman", -"hirer", -"hirmos", -"hiro", -"hirple", -"hirse", -"hirsel", -"hirsle", -"hirsute", -"his", -"hish", -"hisn", -"hispid", -"hiss", -"hisser", -"hissing", -"hist", -"histie", -"histoid", -"histon", -"histone", -"history", -"histrio", -"hit", -"hitch", -"hitcher", -"hitchy", -"hithe", -"hither", -"hitless", -"hitter", -"hive", -"hiver", -"hives", -"hizz", -"ho", -"hoar", -"hoard", -"hoarder", -"hoarily", -"hoarish", -"hoarse", -"hoarsen", -"hoary", -"hoast", -"hoatzin", -"hoax", -"hoaxee", -"hoaxer", -"hob", -"hobber", -"hobbet", -"hobbil", -"hobble", -"hobbler", -"hobbly", -"hobby", -"hoblike", -"hobnail", -"hobnob", -"hobo", -"hoboism", -"hocco", -"hock", -"hocker", -"hocket", -"hockey", -"hocky", -"hocus", -"hod", -"hodden", -"hodder", -"hoddle", -"hoddy", -"hodful", -"hodman", -"hoe", -"hoecake", -"hoedown", -"hoeful", -"hoer", -"hog", -"hoga", -"hogan", -"hogback", -"hogbush", -"hogfish", -"hogged", -"hogger", -"hoggery", -"hogget", -"hoggie", -"hoggin", -"hoggish", -"hoggism", -"hoggy", -"hogherd", -"hoghide", -"hoghood", -"hoglike", -"hogling", -"hogmace", -"hognose", -"hognut", -"hogpen", -"hogship", -"hogskin", -"hogsty", -"hogward", -"hogwash", -"hogweed", -"hogwort", -"hogyard", -"hoi", -"hoick", -"hoin", -"hoise", -"hoist", -"hoister", -"hoit", -"hoju", -"hokey", -"hokum", -"holard", -"holcad", -"hold", -"holdall", -"holden", -"holder", -"holding", -"holdout", -"holdup", -"hole", -"holeman", -"holer", -"holey", -"holia", -"holiday", -"holily", -"holing", -"holism", -"holl", -"holla", -"holler", -"hollin", -"hollo", -"hollock", -"hollong", -"hollow", -"holly", -"holm", -"holmia", -"holmic", -"holmium", -"holmos", -"holour", -"holster", -"holt", -"holy", -"holyday", -"homage", -"homager", -"home", -"homelet", -"homely", -"homelyn", -"homeoid", -"homer", -"homey", -"homily", -"hominal", -"hominid", -"hominy", -"homish", -"homo", -"homodox", -"homogen", -"homonym", -"homrai", -"homy", -"honda", -"hondo", -"hone", -"honest", -"honesty", -"honey", -"honeyed", -"hong", -"honied", -"honily", -"honk", -"honker", -"honor", -"honoree", -"honorer", -"hontish", -"hontous", -"hooch", -"hood", -"hoodcap", -"hooded", -"hoodful", -"hoodie", -"hoodlum", -"hoodman", -"hoodoo", -"hoodshy", -"hooey", -"hoof", -"hoofed", -"hoofer", -"hoofish", -"hooflet", -"hoofrot", -"hoofs", -"hoofy", -"hook", -"hookah", -"hooked", -"hooker", -"hookers", -"hookish", -"hooklet", -"hookman", -"hooktip", -"hookum", -"hookup", -"hooky", -"hoolock", -"hooly", -"hoon", -"hoop", -"hooped", -"hooper", -"hooping", -"hoopla", -"hoople", -"hoopman", -"hoopoe", -"hoose", -"hoosh", -"hoot", -"hootay", -"hooter", -"hoove", -"hooven", -"hoovey", -"hop", -"hopbine", -"hopbush", -"hope", -"hoped", -"hopeful", -"hopeite", -"hoper", -"hopi", -"hoplite", -"hopoff", -"hopped", -"hopper", -"hoppers", -"hoppet", -"hoppity", -"hopple", -"hoppy", -"hoptoad", -"hopvine", -"hopyard", -"hora", -"horal", -"horary", -"hordary", -"horde", -"hordein", -"horizon", -"horme", -"hormic", -"hormigo", -"hormion", -"hormist", -"hormone", -"hormos", -"horn", -"horned", -"horner", -"hornet", -"hornety", -"hornful", -"hornify", -"hornily", -"horning", -"hornish", -"hornist", -"hornito", -"hornlet", -"horntip", -"horny", -"horrent", -"horreum", -"horrid", -"horrify", -"horror", -"horse", -"horser", -"horsify", -"horsily", -"horsing", -"horst", -"horsy", -"hortite", -"hory", -"hosanna", -"hose", -"hosed", -"hosel", -"hoseman", -"hosier", -"hosiery", -"hospice", -"host", -"hostage", -"hostel", -"hoster", -"hostess", -"hostie", -"hostile", -"hosting", -"hostler", -"hostly", -"hostry", -"hot", -"hotbed", -"hotbox", -"hotch", -"hotel", -"hotfoot", -"hothead", -"hoti", -"hotly", -"hotness", -"hotspur", -"hotter", -"hottery", -"hottish", -"houbara", -"hough", -"hougher", -"hounce", -"hound", -"hounder", -"houndy", -"hour", -"hourful", -"houri", -"hourly", -"housage", -"housal", -"house", -"housel", -"houser", -"housing", -"housty", -"housy", -"houtou", -"houvari", -"hove", -"hovel", -"hoveler", -"hoven", -"hover", -"hoverer", -"hoverly", -"how", -"howadji", -"howbeit", -"howdah", -"howder", -"howdie", -"howdy", -"howe", -"howel", -"however", -"howff", -"howish", -"howk", -"howkit", -"howl", -"howler", -"howlet", -"howling", -"howlite", -"howso", -"hox", -"hoy", -"hoyden", -"hoyle", -"hoyman", -"huaca", -"huaco", -"huarizo", -"hub", -"hubb", -"hubba", -"hubber", -"hubble", -"hubbly", -"hubbub", -"hubby", -"hubshi", -"huchen", -"hucho", -"huck", -"huckle", -"hud", -"huddle", -"huddler", -"huddock", -"huddup", -"hue", -"hued", -"hueful", -"hueless", -"huer", -"huff", -"huffier", -"huffily", -"huffish", -"huffle", -"huffler", -"huffy", -"hug", -"huge", -"hugely", -"hugeous", -"hugger", -"hugging", -"huggle", -"hugsome", -"huh", -"huia", -"huipil", -"huitain", -"huke", -"hula", -"huldee", -"hulk", -"hulkage", -"hulking", -"hulky", -"hull", -"huller", -"hullock", -"hulloo", -"hulsite", -"hulster", -"hulu", -"hulver", -"hum", -"human", -"humane", -"humanly", -"humate", -"humble", -"humbler", -"humblie", -"humbly", -"humbo", -"humbug", -"humbuzz", -"humdrum", -"humect", -"humeral", -"humeri", -"humerus", -"humet", -"humetty", -"humhum", -"humic", -"humid", -"humidly", -"humidor", -"humific", -"humify", -"humin", -"humite", -"humlie", -"hummel", -"hummer", -"hummie", -"humming", -"hummock", -"humor", -"humoral", -"humous", -"hump", -"humped", -"humph", -"humpty", -"humpy", -"humus", -"hunch", -"hunchet", -"hunchy", -"hundi", -"hundred", -"hung", -"hunger", -"hungry", -"hunh", -"hunk", -"hunker", -"hunkers", -"hunkies", -"hunks", -"hunky", -"hunt", -"hunting", -"hup", -"hura", -"hurdies", -"hurdis", -"hurdle", -"hurdler", -"hurds", -"hure", -"hureek", -"hurgila", -"hurkle", -"hurl", -"hurled", -"hurler", -"hurley", -"hurling", -"hurlock", -"hurly", -"huron", -"hurr", -"hurrah", -"hurried", -"hurrier", -"hurrock", -"hurroo", -"hurry", -"hurst", -"hurt", -"hurted", -"hurter", -"hurtful", -"hurting", -"hurtle", -"hurty", -"husband", -"huse", -"hush", -"hushaby", -"husheen", -"hushel", -"husher", -"hushful", -"hushing", -"hushion", -"husho", -"husk", -"husked", -"husker", -"huskily", -"husking", -"husky", -"huso", -"huspil", -"huss", -"hussar", -"hussy", -"husting", -"hustle", -"hustler", -"hut", -"hutch", -"hutcher", -"hutchet", -"huthold", -"hutia", -"hutlet", -"hutment", -"huvelyk", -"huzoor", -"huzz", -"huzza", -"huzzard", -"hyaena", -"hyaline", -"hyalite", -"hyaloid", -"hybosis", -"hybrid", -"hydatid", -"hydnoid", -"hydrant", -"hydrate", -"hydrazo", -"hydria", -"hydric", -"hydride", -"hydro", -"hydroa", -"hydroid", -"hydrol", -"hydrome", -"hydrone", -"hydrops", -"hydrous", -"hydroxy", -"hydrula", -"hyena", -"hyenic", -"hyenine", -"hyenoid", -"hyetal", -"hygeist", -"hygiene", -"hygric", -"hygrine", -"hygroma", -"hying", -"hyke", -"hyle", -"hyleg", -"hylic", -"hylism", -"hylist", -"hyloid", -"hymen", -"hymenal", -"hymenic", -"hymn", -"hymnal", -"hymnary", -"hymner", -"hymnic", -"hymnist", -"hymnode", -"hymnody", -"hynde", -"hyne", -"hyoid", -"hyoidal", -"hyoidan", -"hyoides", -"hyp", -"hypate", -"hypaton", -"hyper", -"hypha", -"hyphal", -"hyphema", -"hyphen", -"hypho", -"hypnody", -"hypnoid", -"hypnone", -"hypo", -"hypogee", -"hypoid", -"hyponym", -"hypopus", -"hyporit", -"hyppish", -"hypural", -"hyraces", -"hyracid", -"hyrax", -"hyson", -"hyssop", -"i", -"iamb", -"iambi", -"iambic", -"iambist", -"iambize", -"iambus", -"iao", -"iatric", -"iba", -"iberite", -"ibex", -"ibices", -"ibid", -"ibidine", -"ibis", -"ibolium", -"ibota", -"icaco", -"ice", -"iceberg", -"iceboat", -"icebone", -"icebox", -"icecap", -"iced", -"icefall", -"icefish", -"iceland", -"iceleaf", -"iceless", -"icelike", -"iceman", -"iceroot", -"icework", -"ich", -"ichnite", -"icho", -"ichor", -"ichthus", -"ichu", -"icica", -"icicle", -"icicled", -"icily", -"iciness", -"icing", -"icon", -"iconic", -"iconism", -"icosian", -"icotype", -"icteric", -"icterus", -"ictic", -"ictuate", -"ictus", -"icy", -"id", -"idalia", -"idant", -"iddat", -"ide", -"idea", -"ideaed", -"ideaful", -"ideal", -"ideally", -"ideate", -"ideist", -"identic", -"ides", -"idgah", -"idiasm", -"idic", -"idiocy", -"idiom", -"idiot", -"idiotcy", -"idiotic", -"idiotry", -"idite", -"iditol", -"idle", -"idleful", -"idleman", -"idler", -"idleset", -"idlety", -"idlish", -"idly", -"idol", -"idola", -"idolify", -"idolism", -"idolist", -"idolize", -"idolous", -"idolum", -"idoneal", -"idorgan", -"idose", -"idryl", -"idyl", -"idyler", -"idylism", -"idylist", -"idylize", -"idyllic", -"ie", -"if", -"ife", -"iffy", -"igloo", -"ignatia", -"ignavia", -"igneous", -"ignify", -"ignite", -"igniter", -"ignitor", -"ignoble", -"ignobly", -"ignore", -"ignorer", -"ignote", -"iguana", -"iguanid", -"ihi", -"ihleite", -"ihram", -"iiwi", -"ijma", -"ijolite", -"ikat", -"ikey", -"ikona", -"ikra", -"ileac", -"ileitis", -"ileon", -"ilesite", -"ileum", -"ileus", -"ilex", -"ilia", -"iliac", -"iliacus", -"iliahi", -"ilial", -"iliau", -"ilicic", -"ilicin", -"ilima", -"ilium", -"ilk", -"ilka", -"ilkane", -"ill", -"illapse", -"illeck", -"illegal", -"illeism", -"illeist", -"illess", -"illfare", -"illicit", -"illish", -"illium", -"illness", -"illocal", -"illogic", -"illoyal", -"illth", -"illude", -"illuder", -"illume", -"illumer", -"illupi", -"illure", -"illusor", -"illy", -"ilot", -"ilvaite", -"image", -"imager", -"imagery", -"imagine", -"imagism", -"imagist", -"imago", -"imam", -"imamah", -"imamate", -"imamic", -"imaret", -"imban", -"imband", -"imbarge", -"imbark", -"imbarn", -"imbased", -"imbat", -"imbauba", -"imbe", -"imbed", -"imber", -"imbibe", -"imbiber", -"imbondo", -"imbosom", -"imbower", -"imbrex", -"imbrue", -"imbrute", -"imbue", -"imburse", -"imi", -"imide", -"imidic", -"imine", -"imino", -"imitant", -"imitate", -"immane", -"immask", -"immense", -"immerd", -"immerge", -"immerit", -"immerse", -"immew", -"immi", -"immit", -"immix", -"immoral", -"immound", -"immund", -"immune", -"immure", -"immute", -"imonium", -"imp", -"impack", -"impact", -"impages", -"impaint", -"impair", -"impala", -"impale", -"impaler", -"impall", -"impalm", -"impalsy", -"impane", -"impanel", -"impar", -"impark", -"imparl", -"impart", -"impasse", -"impaste", -"impasto", -"impave", -"impavid", -"impawn", -"impeach", -"impearl", -"impede", -"impeder", -"impel", -"impen", -"impend", -"impent", -"imperia", -"imperil", -"impest", -"impetre", -"impetus", -"imphee", -"impi", -"impiety", -"impinge", -"impious", -"impish", -"implant", -"implate", -"implead", -"implete", -"implex", -"implial", -"impling", -"implode", -"implore", -"implume", -"imply", -"impofo", -"impone", -"impoor", -"import", -"imposal", -"impose", -"imposer", -"impost", -"impot", -"impound", -"impreg", -"impregn", -"impresa", -"imprese", -"impress", -"imprest", -"imprime", -"imprint", -"improof", -"improve", -"impship", -"impubic", -"impugn", -"impulse", -"impure", -"impute", -"imputer", -"impy", -"imshi", -"imsonic", -"imu", -"in", -"inachid", -"inadept", -"inagile", -"inaja", -"inane", -"inanely", -"inanga", -"inanity", -"inapt", -"inaptly", -"inarch", -"inarm", -"inaugur", -"inaxon", -"inbe", -"inbeing", -"inbent", -"inbirth", -"inblow", -"inblown", -"inboard", -"inbond", -"inborn", -"inbound", -"inbread", -"inbreak", -"inbred", -"inbreed", -"inbring", -"inbuilt", -"inburnt", -"inburst", -"inby", -"incarn", -"incase", -"incast", -"incense", -"incept", -"incest", -"inch", -"inched", -"inchpin", -"incide", -"incisal", -"incise", -"incisor", -"incite", -"inciter", -"incivic", -"incline", -"inclip", -"inclose", -"include", -"inclusa", -"incluse", -"incog", -"income", -"incomer", -"inconnu", -"incrash", -"increep", -"increst", -"incross", -"incrust", -"incubi", -"incubus", -"incudal", -"incudes", -"incult", -"incur", -"incurse", -"incurve", -"incus", -"incuse", -"incut", -"indaba", -"indan", -"indane", -"indart", -"indazin", -"indazol", -"inde", -"indebt", -"indeed", -"indeedy", -"indene", -"indent", -"index", -"indexed", -"indexer", -"indic", -"indican", -"indices", -"indicia", -"indict", -"indign", -"indigo", -"indite", -"inditer", -"indium", -"indogen", -"indole", -"indoles", -"indolyl", -"indoor", -"indoors", -"indorse", -"indoxyl", -"indraft", -"indrawn", -"indri", -"induce", -"induced", -"inducer", -"induct", -"indue", -"indulge", -"indult", -"indulto", -"induna", -"indwell", -"indy", -"indyl", -"indylic", -"inearth", -"inept", -"ineptly", -"inequal", -"inerm", -"inert", -"inertia", -"inertly", -"inesite", -"ineunt", -"inexact", -"inexist", -"inface", -"infall", -"infame", -"infamy", -"infancy", -"infand", -"infang", -"infant", -"infanta", -"infante", -"infarct", -"infare", -"infaust", -"infect", -"infeed", -"infeft", -"infelt", -"infer", -"infern", -"inferno", -"infest", -"infidel", -"infield", -"infill", -"infilm", -"infirm", -"infit", -"infix", -"inflame", -"inflate", -"inflect", -"inflex", -"inflict", -"inflood", -"inflow", -"influx", -"infold", -"inform", -"infra", -"infract", -"infula", -"infuse", -"infuser", -"ing", -"ingate", -"ingenit", -"ingenue", -"ingest", -"ingesta", -"ingiver", -"ingle", -"inglobe", -"ingoing", -"ingot", -"ingraft", -"ingrain", -"ingrate", -"ingress", -"ingross", -"ingrow", -"ingrown", -"inguen", -"ingulf", -"inhabit", -"inhale", -"inhaler", -"inhaul", -"inhaust", -"inhere", -"inherit", -"inhiate", -"inhibit", -"inhuman", -"inhume", -"inhumer", -"inial", -"iniome", -"inion", -"initial", -"initis", -"initive", -"inject", -"injelly", -"injunct", -"injure", -"injured", -"injurer", -"injury", -"ink", -"inkbush", -"inken", -"inker", -"inket", -"inkfish", -"inkhorn", -"inkish", -"inkle", -"inkless", -"inklike", -"inkling", -"inknot", -"inkosi", -"inkpot", -"inkroot", -"inks", -"inkshed", -"inkweed", -"inkwell", -"inkwood", -"inky", -"inlaid", -"inlaik", -"inlake", -"inland", -"inlaut", -"inlaw", -"inlawry", -"inlay", -"inlayer", -"inleak", -"inlet", -"inlier", -"inlook", -"inly", -"inlying", -"inmate", -"inmeats", -"inmost", -"inn", -"innate", -"inneity", -"inner", -"innerly", -"innerve", -"inness", -"innest", -"innet", -"inning", -"innless", -"innyard", -"inocyte", -"inogen", -"inoglia", -"inolith", -"inoma", -"inone", -"inopine", -"inorb", -"inosic", -"inosin", -"inosite", -"inower", -"inphase", -"inport", -"inpour", -"inpush", -"input", -"inquest", -"inquiet", -"inquire", -"inquiry", -"inring", -"inro", -"inroad", -"inroll", -"inrub", -"inrun", -"inrush", -"insack", -"insane", -"insculp", -"insea", -"inseam", -"insect", -"insee", -"inseer", -"insense", -"insert", -"inset", -"inshave", -"inshell", -"inship", -"inshoe", -"inshoot", -"inshore", -"inside", -"insider", -"insight", -"insigne", -"insipid", -"insist", -"insnare", -"insofar", -"insole", -"insolid", -"insooth", -"insorb", -"insoul", -"inspan", -"inspeak", -"inspect", -"inspire", -"inspoke", -"install", -"instant", -"instar", -"instate", -"instead", -"insteam", -"insteep", -"instep", -"instill", -"insula", -"insular", -"insulin", -"insulse", -"insult", -"insunk", -"insure", -"insured", -"insurer", -"insurge", -"inswamp", -"inswell", -"inswept", -"inswing", -"intact", -"intake", -"intaker", -"integer", -"inteind", -"intend", -"intense", -"intent", -"inter", -"interim", -"intern", -"intext", -"inthrow", -"intil", -"intima", -"intimal", -"intine", -"into", -"intoed", -"intone", -"intoner", -"intort", -"intown", -"intrada", -"intrait", -"intrant", -"intreat", -"intrine", -"introit", -"intrude", -"intruse", -"intrust", -"intube", -"intue", -"intuent", -"intuit", -"inturn", -"intwist", -"inula", -"inulase", -"inulin", -"inuloid", -"inunct", -"inure", -"inured", -"inurn", -"inutile", -"invade", -"invader", -"invalid", -"inveigh", -"inveil", -"invein", -"invent", -"inverse", -"invert", -"invest", -"invigor", -"invised", -"invital", -"invite", -"invitee", -"inviter", -"invivid", -"invoice", -"invoke", -"invoker", -"involve", -"inwale", -"inwall", -"inward", -"inwards", -"inweave", -"inweed", -"inwick", -"inwind", -"inwit", -"inwith", -"inwood", -"inwork", -"inworn", -"inwound", -"inwoven", -"inwrap", -"inwrit", -"inyoite", -"inyoke", -"io", -"iodate", -"iodic", -"iodide", -"iodine", -"iodism", -"iodite", -"iodize", -"iodizer", -"iodo", -"iodol", -"iodoso", -"iodous", -"iodoxy", -"iolite", -"ion", -"ionic", -"ionium", -"ionize", -"ionizer", -"ionogen", -"ionone", -"iota", -"iotize", -"ipecac", -"ipid", -"ipil", -"ipomea", -"ipseand", -"ipseity", -"iracund", -"irade", -"irate", -"irately", -"ire", -"ireful", -"ireless", -"irene", -"irenic", -"irenics", -"irian", -"irid", -"iridal", -"iridate", -"irides", -"iridial", -"iridian", -"iridic", -"iridin", -"iridine", -"iridite", -"iridium", -"iridize", -"iris", -"irised", -"irisin", -"iritic", -"iritis", -"irk", -"irksome", -"irok", -"iroko", -"iron", -"irone", -"ironer", -"ironice", -"ironish", -"ironism", -"ironist", -"ironize", -"ironly", -"ironman", -"irony", -"irrisor", -"irrupt", -"is", -"isagoge", -"isagon", -"isamine", -"isatate", -"isatic", -"isatide", -"isatin", -"isazoxy", -"isba", -"ischiac", -"ischial", -"ischium", -"ischury", -"iserine", -"iserite", -"isidium", -"isidoid", -"island", -"islandy", -"islay", -"isle", -"islet", -"isleted", -"islot", -"ism", -"ismal", -"ismatic", -"ismdom", -"ismy", -"iso", -"isoamyl", -"isobar", -"isobare", -"isobase", -"isobath", -"isochor", -"isocola", -"isocrat", -"isodont", -"isoflor", -"isogamy", -"isogen", -"isogeny", -"isogon", -"isogram", -"isohel", -"isohyet", -"isolate", -"isology", -"isomer", -"isomere", -"isomery", -"isoneph", -"isonomy", -"isonym", -"isonymy", -"isopag", -"isopod", -"isopoly", -"isoptic", -"isopyre", -"isotac", -"isotely", -"isotome", -"isotony", -"isotope", -"isotopy", -"isotron", -"isotype", -"isoxime", -"issei", -"issite", -"issuant", -"issue", -"issuer", -"issuing", -"ist", -"isthmi", -"isthmic", -"isthmus", -"istle", -"istoke", -"isuret", -"isuroid", -"it", -"itacism", -"itacist", -"italics", -"italite", -"itch", -"itching", -"itchy", -"itcze", -"item", -"iteming", -"itemize", -"itemy", -"iter", -"iterant", -"iterate", -"ither", -"itmo", -"itoubou", -"its", -"itself", -"iturite", -"itzebu", -"iva", -"ivied", -"ivin", -"ivoried", -"ivorine", -"ivorist", -"ivory", -"ivy", -"ivylike", -"ivyweed", -"ivywood", -"ivywort", -"iwa", -"iwaiwa", -"iwis", -"ixodian", -"ixodic", -"ixodid", -"iyo", -"izar", -"izard", -"izle", -"izote", -"iztle", -"izzard", -"j", -"jab", -"jabbed", -"jabber", -"jabbing", -"jabble", -"jabers", -"jabia", -"jabiru", -"jabot", -"jabul", -"jacal", -"jacamar", -"jacami", -"jacamin", -"jacana", -"jacare", -"jacate", -"jacchus", -"jacent", -"jacinth", -"jack", -"jackal", -"jackass", -"jackbox", -"jackboy", -"jackdaw", -"jackeen", -"jacker", -"jacket", -"jackety", -"jackleg", -"jackman", -"jacko", -"jackrod", -"jacksaw", -"jacktan", -"jacobus", -"jacoby", -"jaconet", -"jactant", -"jacu", -"jacuaru", -"jadder", -"jade", -"jaded", -"jadedly", -"jadeite", -"jadery", -"jadish", -"jady", -"jaeger", -"jag", -"jagat", -"jager", -"jagged", -"jagger", -"jaggery", -"jaggy", -"jagir", -"jagla", -"jagless", -"jagong", -"jagrata", -"jagua", -"jaguar", -"jail", -"jailage", -"jaildom", -"jailer", -"jailish", -"jajman", -"jake", -"jakes", -"jako", -"jalap", -"jalapa", -"jalapin", -"jalkar", -"jalopy", -"jalouse", -"jam", -"jama", -"jaman", -"jamb", -"jambeau", -"jambo", -"jambone", -"jambool", -"jambosa", -"jamdani", -"jami", -"jamlike", -"jammer", -"jammy", -"jampan", -"jampani", -"jamwood", -"janapa", -"janapan", -"jane", -"jangada", -"jangkar", -"jangle", -"jangler", -"jangly", -"janitor", -"jank", -"janker", -"jann", -"jannock", -"jantu", -"janua", -"jaob", -"jap", -"japan", -"jape", -"japer", -"japery", -"japing", -"japish", -"jaquima", -"jar", -"jara", -"jaragua", -"jarbird", -"jarble", -"jarbot", -"jarfly", -"jarful", -"jarg", -"jargon", -"jarkman", -"jarl", -"jarldom", -"jarless", -"jarnut", -"jarool", -"jarra", -"jarrah", -"jarring", -"jarry", -"jarvey", -"jasey", -"jaseyed", -"jasmine", -"jasmone", -"jasper", -"jaspery", -"jaspis", -"jaspoid", -"jass", -"jassid", -"jassoid", -"jatha", -"jati", -"jato", -"jaudie", -"jauk", -"jaun", -"jaunce", -"jaunder", -"jaunt", -"jauntie", -"jaunty", -"jaup", -"javali", -"javelin", -"javer", -"jaw", -"jawab", -"jawbone", -"jawed", -"jawfall", -"jawfish", -"jawfoot", -"jawless", -"jawy", -"jay", -"jayhawk", -"jaypie", -"jaywalk", -"jazz", -"jazzer", -"jazzily", -"jazzy", -"jealous", -"jean", -"jeans", -"jecoral", -"jecorin", -"jed", -"jedcock", -"jedding", -"jeddock", -"jeel", -"jeep", -"jeer", -"jeerer", -"jeering", -"jeery", -"jeff", -"jehu", -"jehup", -"jejunal", -"jejune", -"jejunum", -"jelab", -"jelick", -"jell", -"jellica", -"jellico", -"jellied", -"jellify", -"jellily", -"jelloid", -"jelly", -"jemadar", -"jemmily", -"jemmy", -"jenkin", -"jenna", -"jennet", -"jennier", -"jenny", -"jeofail", -"jeopard", -"jerboa", -"jereed", -"jerez", -"jerib", -"jerk", -"jerker", -"jerkily", -"jerkin", -"jerkish", -"jerky", -"jerl", -"jerm", -"jerque", -"jerquer", -"jerry", -"jersey", -"jert", -"jervia", -"jervina", -"jervine", -"jess", -"jessamy", -"jessant", -"jessed", -"jessur", -"jest", -"jestee", -"jester", -"jestful", -"jesting", -"jet", -"jetbead", -"jete", -"jetsam", -"jettage", -"jetted", -"jetter", -"jettied", -"jetton", -"jetty", -"jetware", -"jewbird", -"jewbush", -"jewel", -"jeweler", -"jewelry", -"jewely", -"jewfish", -"jezail", -"jeziah", -"jharal", -"jheel", -"jhool", -"jhow", -"jib", -"jibbah", -"jibber", -"jibby", -"jibe", -"jibhead", -"jibi", -"jibman", -"jiboa", -"jibstay", -"jicama", -"jicara", -"jiff", -"jiffle", -"jiffy", -"jig", -"jigger", -"jiggers", -"jigget", -"jiggety", -"jiggish", -"jiggle", -"jiggly", -"jiggy", -"jiglike", -"jigman", -"jihad", -"jikungu", -"jillet", -"jilt", -"jiltee", -"jilter", -"jiltish", -"jimbang", -"jimjam", -"jimmy", -"jimp", -"jimply", -"jina", -"jing", -"jingal", -"jingle", -"jingled", -"jingler", -"jinglet", -"jingly", -"jingo", -"jinja", -"jinjili", -"jink", -"jinker", -"jinket", -"jinkle", -"jinks", -"jinn", -"jinni", -"jinny", -"jinriki", -"jinx", -"jipper", -"jiqui", -"jirble", -"jirga", -"jiti", -"jitneur", -"jitney", -"jitro", -"jitter", -"jitters", -"jittery", -"jiva", -"jive", -"jixie", -"jo", -"job", -"jobade", -"jobarbe", -"jobber", -"jobbery", -"jobbet", -"jobbing", -"jobbish", -"jobble", -"jobless", -"jobman", -"jobo", -"joch", -"jock", -"jocker", -"jockey", -"jocko", -"jocoque", -"jocose", -"jocote", -"jocu", -"jocular", -"jocum", -"jocuma", -"jocund", -"jodel", -"jodelr", -"joe", -"joebush", -"joewood", -"joey", -"jog", -"jogger", -"joggle", -"joggler", -"joggly", -"johnin", -"join", -"joinant", -"joinder", -"joiner", -"joinery", -"joining", -"joint", -"jointed", -"jointer", -"jointly", -"jointy", -"joist", -"jojoba", -"joke", -"jokelet", -"joker", -"jokish", -"jokist", -"jokul", -"joky", -"joll", -"jollier", -"jollify", -"jollily", -"jollity", -"jollop", -"jolly", -"jolt", -"jolter", -"jolting", -"jolty", -"jonque", -"jonquil", -"joola", -"joom", -"jordan", -"joree", -"jorum", -"joseite", -"josh", -"josher", -"joshi", -"josie", -"joskin", -"joss", -"josser", -"jostle", -"jostler", -"jot", -"jota", -"jotisi", -"jotter", -"jotting", -"jotty", -"joubarb", -"joug", -"jough", -"jouk", -"joule", -"joulean", -"jounce", -"journal", -"journey", -"jours", -"joust", -"jouster", -"jovial", -"jow", -"jowar", -"jowari", -"jowel", -"jower", -"jowery", -"jowl", -"jowler", -"jowlish", -"jowlop", -"jowly", -"jowpy", -"jowser", -"jowter", -"joy", -"joyance", -"joyancy", -"joyant", -"joyful", -"joyhop", -"joyleaf", -"joyless", -"joylet", -"joyous", -"joysome", -"joyweed", -"juba", -"jubate", -"jubbah", -"jubbe", -"jube", -"jubilee", -"jubilus", -"juck", -"juckies", -"jud", -"judcock", -"judex", -"judge", -"judger", -"judices", -"judo", -"jufti", -"jug", -"jugal", -"jugale", -"jugate", -"jugated", -"juger", -"jugerum", -"jugful", -"jugger", -"juggins", -"juggle", -"juggler", -"juglone", -"jugular", -"jugulum", -"jugum", -"juice", -"juicily", -"juicy", -"jujitsu", -"juju", -"jujube", -"jujuism", -"jujuist", -"juke", -"jukebox", -"julep", -"julid", -"julidan", -"julio", -"juloid", -"julole", -"julolin", -"jumart", -"jumba", -"jumble", -"jumbler", -"jumbly", -"jumbo", -"jumbuck", -"jumby", -"jumelle", -"jument", -"jumfru", -"jumma", -"jump", -"jumper", -"jumpy", -"juncite", -"juncous", -"june", -"jungle", -"jungled", -"jungli", -"jungly", -"juniata", -"junior", -"juniper", -"junk", -"junker", -"junket", -"junking", -"junkman", -"junt", -"junta", -"junto", -"jupati", -"jupe", -"jupon", -"jural", -"jurally", -"jurant", -"jurara", -"jurat", -"jurator", -"jure", -"jurel", -"juridic", -"juring", -"jurist", -"juror", -"jury", -"juryman", -"jussel", -"jussion", -"jussive", -"jussory", -"just", -"justen", -"justice", -"justify", -"justly", -"justo", -"jut", -"jute", -"jutka", -"jutting", -"jutty", -"juvenal", -"juvia", -"juvite", -"jyngine", -"jynx", -"k", -"ka", -"kabaya", -"kabel", -"kaberu", -"kabiet", -"kabuki", -"kachin", -"kadaya", -"kadein", -"kados", -"kaffir", -"kafir", -"kafirin", -"kafiz", -"kafta", -"kago", -"kagu", -"kaha", -"kahar", -"kahau", -"kahili", -"kahu", -"kahuna", -"kai", -"kaid", -"kaik", -"kaikara", -"kail", -"kainga", -"kainite", -"kainsi", -"kainyn", -"kairine", -"kaiser", -"kaitaka", -"kaiwi", -"kajawah", -"kaka", -"kakapo", -"kakar", -"kaki", -"kakkak", -"kakke", -"kala", -"kalasie", -"kale", -"kalema", -"kalends", -"kali", -"kalian", -"kalium", -"kallah", -"kallege", -"kalo", -"kalon", -"kalong", -"kalpis", -"kamahi", -"kamala", -"kamansi", -"kamao", -"kamas", -"kamassi", -"kambal", -"kamboh", -"kame", -"kamerad", -"kamias", -"kamichi", -"kamik", -"kampong", -"kan", -"kana", -"kanae", -"kanagi", -"kanap", -"kanara", -"kanari", -"kanat", -"kanchil", -"kande", -"kandol", -"kaneh", -"kang", -"kanga", -"kangani", -"kankie", -"kannume", -"kanoon", -"kans", -"kantele", -"kanten", -"kaolin", -"kapa", -"kapai", -"kapeika", -"kapok", -"kapp", -"kappa", -"kappe", -"kapur", -"kaput", -"karagan", -"karaka", -"karakul", -"karamu", -"karaoke", -"karate", -"karaya", -"karbi", -"karch", -"kareao", -"kareeta", -"karela", -"karite", -"karma", -"karmic", -"karo", -"kaross", -"karou", -"karree", -"karri", -"karroo", -"karsha", -"karst", -"karstic", -"kartel", -"kartos", -"karwar", -"karyon", -"kasa", -"kasbah", -"kasbeke", -"kasher", -"kashga", -"kashi", -"kashima", -"kasida", -"kasm", -"kassu", -"kastura", -"kat", -"katar", -"katcina", -"kath", -"katha", -"kathal", -"katipo", -"katmon", -"katogle", -"katsup", -"katuka", -"katun", -"katurai", -"katydid", -"kauri", -"kava", -"kavaic", -"kavass", -"kawaka", -"kawika", -"kay", -"kayak", -"kayaker", -"kayles", -"kayo", -"kazi", -"kazoo", -"kea", -"keach", -"keacorn", -"keawe", -"keb", -"kebab", -"kebbie", -"kebbuck", -"kechel", -"keck", -"keckle", -"kecksy", -"kecky", -"ked", -"keddah", -"kedge", -"kedger", -"kedlock", -"keech", -"keek", -"keeker", -"keel", -"keelage", -"keeled", -"keeler", -"keelfat", -"keelie", -"keeling", -"keelman", -"keelson", -"keen", -"keena", -"keened", -"keener", -"keenly", -"keep", -"keeper", -"keeping", -"keest", -"keet", -"keeve", -"kef", -"keffel", -"kefir", -"kefiric", -"keg", -"kegler", -"kehaya", -"keita", -"keitloa", -"kekuna", -"kelchin", -"keld", -"kele", -"kelebe", -"keleh", -"kelek", -"kelep", -"kelk", -"kell", -"kella", -"kellion", -"kelly", -"keloid", -"kelp", -"kelper", -"kelpie", -"kelpy", -"kelt", -"kelter", -"kelty", -"kelvin", -"kemb", -"kemp", -"kempite", -"kemple", -"kempt", -"kempy", -"ken", -"kenaf", -"kenareh", -"kench", -"kend", -"kendir", -"kendyr", -"kenlore", -"kenmark", -"kennel", -"kenner", -"kenning", -"kenno", -"keno", -"kenosis", -"kenotic", -"kenspac", -"kent", -"kenyte", -"kep", -"kepi", -"kept", -"kerana", -"kerasin", -"kerat", -"keratin", -"keratto", -"kerchoo", -"kerchug", -"kerel", -"kerf", -"kerflap", -"kerflop", -"kermes", -"kermis", -"kern", -"kernel", -"kerner", -"kernish", -"kernite", -"kernos", -"kerogen", -"kerrie", -"kerril", -"kerrite", -"kerry", -"kersey", -"kerslam", -"kerugma", -"kerwham", -"kerygma", -"kestrel", -"ket", -"keta", -"ketal", -"ketch", -"ketchup", -"keten", -"ketene", -"ketipic", -"keto", -"ketogen", -"ketol", -"ketole", -"ketone", -"ketonic", -"ketose", -"ketosis", -"kette", -"ketting", -"kettle", -"kettler", -"ketty", -"ketuba", -"ketupa", -"ketyl", -"keup", -"kevalin", -"kevel", -"kewpie", -"kex", -"kexy", -"key", -"keyage", -"keyed", -"keyhole", -"keyless", -"keylet", -"keylock", -"keynote", -"keyway", -"khaddar", -"khadi", -"khahoon", -"khaiki", -"khair", -"khaja", -"khajur", -"khaki", -"khakied", -"khalifa", -"khalsa", -"khamsin", -"khan", -"khanate", -"khanda", -"khanjar", -"khanjee", -"khankah", -"khanum", -"khar", -"kharaj", -"kharua", -"khass", -"khat", -"khatib", -"khatri", -"khediva", -"khedive", -"khepesh", -"khet", -"khilat", -"khir", -"khirka", -"khoja", -"khoka", -"khot", -"khu", -"khubber", -"khula", -"khutbah", -"khvat", -"kiack", -"kiaki", -"kialee", -"kiang", -"kiaugh", -"kibber", -"kibble", -"kibbler", -"kibe", -"kibei", -"kibitka", -"kibitz", -"kiblah", -"kibosh", -"kiby", -"kick", -"kickee", -"kicker", -"kicking", -"kickish", -"kickoff", -"kickout", -"kickup", -"kidder", -"kiddier", -"kiddish", -"kiddush", -"kiddy", -"kidhood", -"kidlet", -"kidling", -"kidnap", -"kidney", -"kidskin", -"kidsman", -"kiekie", -"kiel", -"kier", -"kieye", -"kikar", -"kike", -"kiki", -"kiku", -"kikuel", -"kikumon", -"kil", -"kiladja", -"kilah", -"kilan", -"kildee", -"kileh", -"kilerg", -"kiley", -"kilhig", -"kiliare", -"kilim", -"kill", -"killas", -"killcu", -"killeen", -"killer", -"killick", -"killing", -"killy", -"kiln", -"kilneye", -"kilnman", -"kilnrib", -"kilo", -"kilobar", -"kiloton", -"kilovar", -"kilp", -"kilt", -"kilter", -"kiltie", -"kilting", -"kim", -"kimbang", -"kimnel", -"kimono", -"kin", -"kina", -"kinah", -"kinase", -"kinbote", -"kinch", -"kinchin", -"kincob", -"kind", -"kindle", -"kindler", -"kindly", -"kindred", -"kinepox", -"kinesic", -"kinesis", -"kinetic", -"king", -"kingcob", -"kingcup", -"kingdom", -"kinglet", -"kingly", -"kingpin", -"kingrow", -"kink", -"kinkhab", -"kinkily", -"kinkle", -"kinkled", -"kinkly", -"kinky", -"kinless", -"kino", -"kinship", -"kinsman", -"kintar", -"kioea", -"kiosk", -"kiotome", -"kip", -"kipage", -"kipe", -"kippeen", -"kipper", -"kippy", -"kipsey", -"kipskin", -"kiri", -"kirimon", -"kirk", -"kirker", -"kirkify", -"kirking", -"kirkman", -"kirmew", -"kirn", -"kirombo", -"kirsch", -"kirtle", -"kirtled", -"kirve", -"kirver", -"kischen", -"kish", -"kishen", -"kishon", -"kishy", -"kismet", -"kisra", -"kiss", -"kissage", -"kissar", -"kisser", -"kissing", -"kissy", -"kist", -"kistful", -"kiswa", -"kit", -"kitab", -"kitabis", -"kitar", -"kitcat", -"kitchen", -"kite", -"kith", -"kithe", -"kitish", -"kitling", -"kittel", -"kitten", -"kitter", -"kittle", -"kittles", -"kittly", -"kittock", -"kittul", -"kitty", -"kiva", -"kiver", -"kivu", -"kiwi", -"kiyas", -"kiyi", -"klafter", -"klam", -"klavern", -"klaxon", -"klepht", -"kleptic", -"klicket", -"klip", -"klipbok", -"klipdas", -"klippe", -"klippen", -"klister", -"klom", -"klop", -"klops", -"klosh", -"kmet", -"knab", -"knabble", -"knack", -"knacker", -"knacky", -"knag", -"knagged", -"knaggy", -"knap", -"knape", -"knappan", -"knapper", -"knar", -"knark", -"knarred", -"knarry", -"knave", -"knavery", -"knavess", -"knavish", -"knawel", -"knead", -"kneader", -"knee", -"kneecap", -"kneed", -"kneel", -"kneeler", -"kneelet", -"kneepad", -"kneepan", -"knell", -"knelt", -"knet", -"knew", -"knez", -"knezi", -"kniaz", -"kniazi", -"knick", -"knicker", -"knife", -"knifer", -"knight", -"knit", -"knitch", -"knitted", -"knitter", -"knittle", -"knived", -"knivey", -"knob", -"knobbed", -"knobber", -"knobble", -"knobbly", -"knobby", -"knock", -"knocker", -"knockup", -"knoll", -"knoller", -"knolly", -"knop", -"knopite", -"knopped", -"knopper", -"knoppy", -"knosp", -"knosped", -"knot", -"knotted", -"knotter", -"knotty", -"knout", -"know", -"knowe", -"knower", -"knowing", -"known", -"knub", -"knubbly", -"knubby", -"knublet", -"knuckle", -"knuckly", -"knur", -"knurl", -"knurled", -"knurly", -"knut", -"knutty", -"knyaz", -"knyazi", -"ko", -"koa", -"koae", -"koala", -"koali", -"kob", -"koban", -"kobi", -"kobird", -"kobold", -"kobong", -"kobu", -"koda", -"kodak", -"kodaker", -"kodakry", -"kodro", -"koel", -"koff", -"koft", -"koftgar", -"kohemp", -"kohl", -"kohua", -"koi", -"koil", -"koila", -"koilon", -"koine", -"koinon", -"kojang", -"kokako", -"kokam", -"kokan", -"kokil", -"kokio", -"koklas", -"koklass", -"koko", -"kokoon", -"kokowai", -"kokra", -"koku", -"kokum", -"kokumin", -"kola", -"kolach", -"kolea", -"kolhoz", -"kolkhos", -"kolkhoz", -"kollast", -"koller", -"kolo", -"kolobus", -"kolsun", -"komatik", -"kombu", -"kommos", -"kompeni", -"kon", -"kona", -"konak", -"kongoni", -"kongu", -"konini", -"konjak", -"kooka", -"kookery", -"kookri", -"koolah", -"koombar", -"koomkie", -"kootcha", -"kop", -"kopeck", -"koph", -"kopi", -"koppa", -"koppen", -"koppite", -"kor", -"kora", -"koradji", -"korait", -"korakan", -"korari", -"kore", -"korec", -"koreci", -"korero", -"kori", -"korin", -"korona", -"korova", -"korrel", -"koruna", -"korzec", -"kos", -"kosher", -"kosin", -"kosong", -"koswite", -"kotal", -"koto", -"kotuku", -"kotwal", -"kotyle", -"kotylos", -"kou", -"koulan", -"kouza", -"kovil", -"kowhai", -"kowtow", -"koyan", -"kozo", -"kra", -"kraal", -"kraft", -"krait", -"kraken", -"kral", -"krama", -"kran", -"kras", -"krasis", -"krausen", -"kraut", -"kreis", -"krelos", -"kremlin", -"krems", -"kreng", -"krieker", -"krimmer", -"krina", -"krocket", -"krome", -"krona", -"krone", -"kronen", -"kroner", -"kronor", -"kronur", -"kroon", -"krosa", -"krypsis", -"kryptic", -"kryptol", -"krypton", -"kuan", -"kuba", -"kubba", -"kuchen", -"kudize", -"kudos", -"kudu", -"kudzu", -"kuei", -"kuge", -"kugel", -"kuichua", -"kukri", -"kuku", -"kukui", -"kukupa", -"kula", -"kulack", -"kulah", -"kulaite", -"kulak", -"kulang", -"kulimit", -"kulm", -"kulmet", -"kumbi", -"kumhar", -"kumiss", -"kummel", -"kumquat", -"kumrah", -"kunai", -"kung", -"kunk", -"kunkur", -"kunzite", -"kuphar", -"kupper", -"kurbash", -"kurgan", -"kuruma", -"kurung", -"kurus", -"kurvey", -"kusa", -"kusam", -"kusha", -"kuskite", -"kuskos", -"kuskus", -"kusti", -"kusum", -"kutcha", -"kuttab", -"kuttar", -"kuttaur", -"kuvasz", -"kvass", -"kvint", -"kvinter", -"kwamme", -"kwan", -"kwarta", -"kwazoku", -"kyack", -"kyah", -"kyar", -"kyat", -"kyaung", -"kyl", -"kyle", -"kylite", -"kylix", -"kyrine", -"kyte", -"l", -"la", -"laager", -"laang", -"lab", -"labara", -"labarum", -"labba", -"labber", -"labefy", -"label", -"labeler", -"labella", -"labia", -"labial", -"labiate", -"labile", -"labiose", -"labis", -"labium", -"lablab", -"labor", -"labored", -"laborer", -"labour", -"labra", -"labral", -"labret", -"labroid", -"labrose", -"labrum", -"labrys", -"lac", -"lacca", -"laccaic", -"laccase", -"laccol", -"lace", -"laced", -"laceman", -"lacepod", -"lacer", -"lacery", -"lacet", -"lache", -"laches", -"lachsa", -"lacily", -"lacing", -"lacinia", -"lacis", -"lack", -"lacker", -"lackey", -"lackwit", -"lacmoid", -"lacmus", -"laconic", -"lacquer", -"lacrym", -"lactam", -"lactant", -"lactary", -"lactase", -"lactate", -"lacteal", -"lactean", -"lactic", -"lactid", -"lactide", -"lactify", -"lactim", -"lacto", -"lactoid", -"lactol", -"lactone", -"lactose", -"lactyl", -"lacuna", -"lacunae", -"lacunal", -"lacunar", -"lacune", -"lacwork", -"lacy", -"lad", -"ladakin", -"ladanum", -"ladder", -"laddery", -"laddess", -"laddie", -"laddish", -"laddock", -"lade", -"lademan", -"laden", -"lader", -"ladhood", -"ladies", -"ladify", -"lading", -"ladkin", -"ladle", -"ladler", -"ladrone", -"lady", -"ladybug", -"ladydom", -"ladyfly", -"ladyfy", -"ladyish", -"ladyism", -"ladykin", -"ladyly", -"laet", -"laeti", -"laetic", -"lag", -"lagan", -"lagarto", -"lagen", -"lagena", -"lagend", -"lager", -"lagetto", -"laggar", -"laggard", -"lagged", -"laggen", -"lagger", -"laggin", -"lagging", -"laglast", -"lagna", -"lagoon", -"lagwort", -"lai", -"laic", -"laical", -"laich", -"laicism", -"laicity", -"laicize", -"laid", -"laigh", -"lain", -"laine", -"laiose", -"lair", -"lairage", -"laird", -"lairdie", -"lairdly", -"lairman", -"lairy", -"laity", -"lak", -"lakatoi", -"lake", -"lakelet", -"laker", -"lakie", -"laking", -"lakish", -"lakism", -"lakist", -"laky", -"lalang", -"lall", -"lalling", -"lalo", -"lam", -"lama", -"lamaic", -"lamany", -"lamb", -"lamba", -"lambale", -"lambda", -"lambeau", -"lambent", -"lamber", -"lambert", -"lambie", -"lambish", -"lambkin", -"lambly", -"lamboys", -"lamby", -"lame", -"lamedh", -"lamel", -"lamella", -"lamely", -"lament", -"lameter", -"lametta", -"lamia", -"lamiger", -"lamiid", -"lamin", -"lamina", -"laminae", -"laminar", -"lamish", -"lamiter", -"lammas", -"lammer", -"lammock", -"lammy", -"lamnid", -"lamnoid", -"lamp", -"lampad", -"lampas", -"lamper", -"lampern", -"lampers", -"lampfly", -"lampful", -"lamping", -"lampion", -"lampist", -"lamplet", -"lamplit", -"lampman", -"lampoon", -"lamprey", -"lan", -"lanas", -"lanate", -"lanated", -"lanaz", -"lance", -"lanced", -"lancely", -"lancer", -"lances", -"lancet", -"lancha", -"land", -"landau", -"landed", -"lander", -"landing", -"landman", -"landmil", -"lane", -"lanete", -"laneway", -"laney", -"langaha", -"langca", -"langi", -"langite", -"langle", -"langoon", -"langsat", -"langued", -"languet", -"languid", -"languor", -"langur", -"laniary", -"laniate", -"lanific", -"lanioid", -"lanista", -"lank", -"lanket", -"lankily", -"lankish", -"lankly", -"lanky", -"lanner", -"lanolin", -"lanose", -"lansat", -"lanseh", -"lanson", -"lant", -"lantaca", -"lantern", -"lantum", -"lanugo", -"lanum", -"lanx", -"lanyard", -"lap", -"lapacho", -"lapcock", -"lapel", -"lapeler", -"lapful", -"lapillo", -"lapon", -"lappage", -"lapped", -"lapper", -"lappet", -"lapping", -"lapse", -"lapsed", -"lapser", -"lapsi", -"lapsing", -"lapwing", -"lapwork", -"laquear", -"laqueus", -"lar", -"larceny", -"larch", -"larchen", -"lard", -"larder", -"lardite", -"lardon", -"lardy", -"large", -"largely", -"largen", -"largess", -"largish", -"largo", -"lari", -"lariat", -"larick", -"larid", -"larigo", -"larigot", -"lariid", -"larin", -"larine", -"larixin", -"lark", -"larker", -"larking", -"larkish", -"larky", -"larmier", -"larnax", -"laroid", -"larrup", -"larry", -"larva", -"larvae", -"larval", -"larvate", -"larve", -"larvule", -"larynx", -"las", -"lasa", -"lascar", -"laser", -"lash", -"lasher", -"lask", -"lasket", -"lasque", -"lass", -"lasset", -"lassie", -"lasso", -"lassock", -"lassoer", -"last", -"lastage", -"laster", -"lasting", -"lastly", -"lastre", -"lasty", -"lat", -"lata", -"latah", -"latch", -"latcher", -"latchet", -"late", -"latebra", -"lated", -"lateen", -"lately", -"laten", -"latence", -"latency", -"latent", -"later", -"latera", -"laterad", -"lateral", -"latest", -"latex", -"lath", -"lathe", -"lathee", -"lathen", -"lather", -"lathery", -"lathing", -"lathy", -"latices", -"latigo", -"lation", -"latish", -"latitat", -"latite", -"latomy", -"latrant", -"latria", -"latrine", -"latro", -"latrobe", -"latron", -"latten", -"latter", -"lattice", -"latus", -"lauan", -"laud", -"lauder", -"laudist", -"laugh", -"laughee", -"laugher", -"laughy", -"lauia", -"laun", -"launce", -"launch", -"laund", -"launder", -"laundry", -"laur", -"laura", -"laurate", -"laurel", -"lauric", -"laurin", -"laurite", -"laurone", -"lauryl", -"lava", -"lavable", -"lavabo", -"lavacre", -"lavage", -"lavanga", -"lavant", -"lavaret", -"lavatic", -"lave", -"laveer", -"laver", -"lavic", -"lavish", -"lavolta", -"law", -"lawbook", -"lawful", -"lawing", -"lawish", -"lawk", -"lawless", -"lawlike", -"lawman", -"lawn", -"lawned", -"lawner", -"lawnlet", -"lawny", -"lawsuit", -"lawter", -"lawyer", -"lawyery", -"lawzy", -"lax", -"laxate", -"laxism", -"laxist", -"laxity", -"laxly", -"laxness", -"lay", -"layaway", -"layback", -"layboy", -"layer", -"layered", -"layery", -"layette", -"laying", -"layland", -"layman", -"layne", -"layoff", -"layout", -"layover", -"layship", -"laystow", -"lazar", -"lazaret", -"lazarly", -"laze", -"lazily", -"lazule", -"lazuli", -"lazy", -"lazyish", -"lea", -"leach", -"leacher", -"leachy", -"lead", -"leadage", -"leaded", -"leaden", -"leader", -"leadin", -"leading", -"leadman", -"leadoff", -"leadout", -"leadway", -"leady", -"leaf", -"leafage", -"leafboy", -"leafcup", -"leafdom", -"leafed", -"leafen", -"leafer", -"leafery", -"leafit", -"leaflet", -"leafy", -"league", -"leaguer", -"leak", -"leakage", -"leaker", -"leaky", -"leal", -"lealand", -"leally", -"lealty", -"leam", -"leamer", -"lean", -"leaner", -"leaning", -"leanish", -"leanly", -"leant", -"leap", -"leaper", -"leaping", -"leapt", -"lear", -"learn", -"learned", -"learner", -"learnt", -"lease", -"leaser", -"leash", -"leasing", -"leasow", -"least", -"leat", -"leath", -"leather", -"leatman", -"leave", -"leaved", -"leaven", -"leaver", -"leaves", -"leaving", -"leavy", -"leawill", -"leban", -"lebbek", -"lecama", -"lech", -"lecher", -"lechery", -"lechwe", -"leck", -"lecker", -"lectern", -"lection", -"lector", -"lectual", -"lecture", -"lecyth", -"led", -"lede", -"leden", -"ledge", -"ledged", -"ledger", -"ledging", -"ledgy", -"ledol", -"lee", -"leech", -"leecher", -"leeches", -"leed", -"leefang", -"leek", -"leekish", -"leeky", -"leep", -"leepit", -"leer", -"leerily", -"leerish", -"leery", -"lees", -"leet", -"leetman", -"leewan", -"leeward", -"leeway", -"leewill", -"left", -"leftish", -"leftism", -"leftist", -"leg", -"legacy", -"legal", -"legally", -"legate", -"legatee", -"legato", -"legator", -"legend", -"legenda", -"leger", -"leges", -"legged", -"legger", -"legging", -"leggy", -"leghorn", -"legible", -"legibly", -"legific", -"legion", -"legist", -"legit", -"legitim", -"leglen", -"legless", -"leglet", -"leglike", -"legman", -"legoa", -"legpull", -"legrope", -"legua", -"leguan", -"legume", -"legumen", -"legumin", -"lehr", -"lehrman", -"lehua", -"lei", -"leister", -"leisure", -"lek", -"lekach", -"lekane", -"lekha", -"leman", -"lemel", -"lemma", -"lemmata", -"lemming", -"lemnad", -"lemon", -"lemony", -"lempira", -"lemur", -"lemures", -"lemurid", -"lenad", -"lenard", -"lench", -"lend", -"lendee", -"lender", -"lene", -"length", -"lengthy", -"lenient", -"lenify", -"lenis", -"lenitic", -"lenity", -"lennow", -"leno", -"lens", -"lensed", -"lent", -"lenth", -"lentigo", -"lentil", -"lentisc", -"lentisk", -"lento", -"lentoid", -"lentor", -"lentous", -"lenvoi", -"lenvoy", -"leonine", -"leonite", -"leopard", -"leotard", -"lepa", -"leper", -"lepered", -"leporid", -"lepra", -"lepric", -"leproid", -"leproma", -"leprose", -"leprosy", -"leprous", -"leptid", -"leptite", -"leptome", -"lepton", -"leptus", -"lerot", -"lerp", -"lerret", -"lesche", -"lesion", -"lesiy", -"less", -"lessee", -"lessen", -"lesser", -"lessive", -"lessn", -"lesson", -"lessor", -"lest", -"lestrad", -"let", -"letch", -"letchy", -"letdown", -"lete", -"lethal", -"letoff", -"letten", -"letter", -"lettrin", -"lettuce", -"letup", -"leu", -"leuch", -"leucine", -"leucism", -"leucite", -"leuco", -"leucoid", -"leucoma", -"leucon", -"leucous", -"leucyl", -"leud", -"leuk", -"leuma", -"lev", -"levance", -"levant", -"levator", -"levee", -"level", -"leveler", -"levelly", -"lever", -"leverer", -"leveret", -"levers", -"levier", -"levin", -"levir", -"levity", -"levo", -"levulic", -"levulin", -"levy", -"levyist", -"lew", -"lewd", -"lewdly", -"lewis", -"lewth", -"lexia", -"lexical", -"lexicon", -"ley", -"leyland", -"leysing", -"li", -"liable", -"liaison", -"liana", -"liang", -"liar", -"liard", -"libant", -"libate", -"libber", -"libbet", -"libbra", -"libel", -"libelee", -"libeler", -"liber", -"liberal", -"liberty", -"libido", -"libken", -"libra", -"libral", -"library", -"librate", -"licca", -"license", -"lich", -"licham", -"lichen", -"licheny", -"lichi", -"licit", -"licitly", -"lick", -"licker", -"licking", -"licorn", -"licorne", -"lictor", -"lid", -"lidded", -"lidder", -"lidgate", -"lidless", -"lie", -"lied", -"lief", -"liege", -"liegely", -"lieger", -"lien", -"lienal", -"lienee", -"lienic", -"lienor", -"lier", -"lierne", -"lierre", -"liesh", -"lieu", -"lieue", -"lieve", -"life", -"lifeday", -"lifeful", -"lifelet", -"lifer", -"lifey", -"lifo", -"lift", -"lifter", -"lifting", -"liftman", -"ligable", -"ligas", -"ligate", -"ligator", -"ligger", -"light", -"lighten", -"lighter", -"lightly", -"ligne", -"lignify", -"lignin", -"lignite", -"lignone", -"lignose", -"lignum", -"ligula", -"ligular", -"ligule", -"ligulin", -"ligure", -"liin", -"lija", -"likable", -"like", -"likely", -"liken", -"liker", -"likin", -"liking", -"liknon", -"lilac", -"lilacin", -"lilacky", -"lile", -"lilied", -"lill", -"lilt", -"lily", -"lilyfy", -"lim", -"limacel", -"limacon", -"liman", -"limb", -"limbal", -"limbat", -"limbate", -"limbeck", -"limbed", -"limber", -"limbers", -"limbic", -"limbie", -"limbo", -"limbous", -"limbus", -"limby", -"lime", -"limeade", -"limeman", -"limen", -"limer", -"limes", -"limetta", -"limey", -"liminal", -"liming", -"limit", -"limital", -"limited", -"limiter", -"limma", -"limmer", -"limmock", -"limmu", -"limn", -"limner", -"limnery", -"limniad", -"limnite", -"limoid", -"limonin", -"limose", -"limous", -"limp", -"limper", -"limpet", -"limpid", -"limpily", -"limpin", -"limping", -"limpish", -"limpkin", -"limply", -"limpsy", -"limpy", -"limsy", -"limu", -"limulid", -"limy", -"lin", -"lina", -"linable", -"linaga", -"linage", -"linaloa", -"linalol", -"linch", -"linchet", -"linctus", -"lindane", -"linden", -"linder", -"lindo", -"line", -"linea", -"lineage", -"lineal", -"linear", -"lineate", -"linecut", -"lined", -"linelet", -"lineman", -"linen", -"liner", -"ling", -"linga", -"linge", -"lingel", -"linger", -"lingo", -"lingtow", -"lingua", -"lingual", -"linguet", -"lingula", -"lingy", -"linha", -"linhay", -"linie", -"linin", -"lining", -"linitis", -"liniya", -"linja", -"linje", -"link", -"linkage", -"linkboy", -"linked", -"linker", -"linking", -"linkman", -"links", -"linky", -"linn", -"linnet", -"lino", -"linolic", -"linolin", -"linon", -"linous", -"linoxin", -"linoxyn", -"linpin", -"linseed", -"linsey", -"lint", -"lintel", -"linten", -"linter", -"lintern", -"lintie", -"linty", -"linwood", -"liny", -"lion", -"lioncel", -"lionel", -"lioness", -"lionet", -"lionism", -"lionize", -"lionly", -"lip", -"lipa", -"liparid", -"lipase", -"lipemia", -"lipide", -"lipin", -"lipless", -"liplet", -"liplike", -"lipoid", -"lipoma", -"lipopod", -"liposis", -"lipped", -"lippen", -"lipper", -"lipping", -"lippy", -"lipuria", -"lipwork", -"liquate", -"liquefy", -"liqueur", -"liquid", -"liquidy", -"liquor", -"lira", -"lirate", -"lire", -"lirella", -"lis", -"lisere", -"lish", -"lisk", -"lisle", -"lisp", -"lisper", -"lispund", -"liss", -"lissom", -"lissome", -"list", -"listed", -"listel", -"listen", -"lister", -"listing", -"listred", -"lit", -"litany", -"litas", -"litch", -"litchi", -"lite", -"liter", -"literal", -"lith", -"lithe", -"lithely", -"lithi", -"lithia", -"lithic", -"lithify", -"lithite", -"lithium", -"litho", -"lithoid", -"lithous", -"lithy", -"litmus", -"litotes", -"litra", -"litster", -"litten", -"litter", -"littery", -"little", -"lituite", -"liturgy", -"litus", -"lituus", -"litz", -"livable", -"live", -"lived", -"livedo", -"lively", -"liven", -"liver", -"livered", -"livery", -"livid", -"lividly", -"livier", -"living", -"livor", -"livre", -"liwan", -"lixive", -"lizard", -"llama", -"llano", -"llautu", -"llyn", -"lo", -"loa", -"loach", -"load", -"loadage", -"loaded", -"loaden", -"loader", -"loading", -"loaf", -"loafer", -"loafing", -"loaflet", -"loam", -"loamily", -"loaming", -"loamy", -"loan", -"loaner", -"loanin", -"loath", -"loathe", -"loather", -"loathly", -"loave", -"lob", -"lobal", -"lobar", -"lobate", -"lobated", -"lobber", -"lobbish", -"lobby", -"lobbyer", -"lobcock", -"lobe", -"lobed", -"lobelet", -"lobelin", -"lobfig", -"lobing", -"lobiped", -"lobo", -"lobola", -"lobose", -"lobster", -"lobtail", -"lobular", -"lobule", -"lobworm", -"loca", -"locable", -"local", -"locale", -"locally", -"locanda", -"locate", -"locator", -"loch", -"lochage", -"lochan", -"lochia", -"lochial", -"lochus", -"lochy", -"loci", -"lock", -"lockage", -"lockbox", -"locked", -"locker", -"locket", -"lockful", -"locking", -"lockjaw", -"locklet", -"lockman", -"lockout", -"lockpin", -"lockram", -"lockup", -"locky", -"loco", -"locoism", -"locular", -"locule", -"loculus", -"locum", -"locus", -"locust", -"locusta", -"locutor", -"lod", -"lode", -"lodge", -"lodged", -"lodger", -"lodging", -"loess", -"loessal", -"loessic", -"lof", -"loft", -"lofter", -"loftily", -"lofting", -"loftman", -"lofty", -"log", -"loganin", -"logbook", -"logcock", -"loge", -"logeion", -"logeum", -"loggat", -"logged", -"logger", -"loggia", -"loggin", -"logging", -"loggish", -"loghead", -"logia", -"logic", -"logical", -"logie", -"login", -"logion", -"logium", -"loglet", -"loglike", -"logman", -"logoi", -"logos", -"logroll", -"logway", -"logwise", -"logwood", -"logwork", -"logy", -"lohan", -"lohoch", -"loimic", -"loin", -"loined", -"loir", -"loiter", -"loka", -"lokao", -"lokaose", -"loke", -"loket", -"lokiec", -"loll", -"loller", -"lollop", -"lollopy", -"lolly", -"loma", -"lombard", -"lomboy", -"loment", -"lomita", -"lommock", -"lone", -"lonely", -"long", -"longa", -"longan", -"longbow", -"longe", -"longear", -"longer", -"longfin", -"longful", -"longing", -"longish", -"longjaw", -"longly", -"longs", -"longue", -"longway", -"lontar", -"loo", -"looby", -"lood", -"loof", -"loofah", -"loofie", -"look", -"looker", -"looking", -"lookout", -"lookum", -"loom", -"loomer", -"loomery", -"looming", -"loon", -"loonery", -"looney", -"loony", -"loop", -"looper", -"loopful", -"looping", -"loopist", -"looplet", -"loopy", -"loose", -"loosely", -"loosen", -"looser", -"loosing", -"loosish", -"loot", -"looten", -"looter", -"lootie", -"lop", -"lope", -"loper", -"lophiid", -"lophine", -"loppard", -"lopper", -"loppet", -"lopping", -"loppy", -"lopseed", -"loquat", -"loquent", -"lora", -"loral", -"loran", -"lorate", -"lorcha", -"lord", -"lording", -"lordkin", -"lordlet", -"lordly", -"lordy", -"lore", -"loreal", -"lored", -"lori", -"loric", -"lorica", -"lorilet", -"lorimer", -"loriot", -"loris", -"lormery", -"lorn", -"loro", -"lorry", -"lors", -"lorum", -"lory", -"losable", -"lose", -"losel", -"loser", -"losh", -"losing", -"loss", -"lost", -"lot", -"lota", -"lotase", -"lote", -"lotic", -"lotion", -"lotment", -"lotrite", -"lots", -"lotter", -"lottery", -"lotto", -"lotus", -"lotusin", -"louch", -"loud", -"louden", -"loudish", -"loudly", -"louey", -"lough", -"louk", -"loukoum", -"loulu", -"lounder", -"lounge", -"lounger", -"loungy", -"loup", -"loupe", -"lour", -"lourdy", -"louse", -"lousily", -"louster", -"lousy", -"lout", -"louter", -"louther", -"loutish", -"louty", -"louvar", -"louver", -"lovable", -"lovably", -"lovage", -"love", -"loveful", -"lovely", -"loveman", -"lover", -"lovered", -"loverly", -"loving", -"low", -"lowa", -"lowan", -"lowbell", -"lowborn", -"lowboy", -"lowbred", -"lowdah", -"lowder", -"loweite", -"lower", -"lowerer", -"lowery", -"lowish", -"lowland", -"lowlily", -"lowly", -"lowmen", -"lowmost", -"lown", -"lowness", -"lownly", -"lowth", -"lowwood", -"lowy", -"lox", -"loxia", -"loxic", -"loxotic", -"loy", -"loyal", -"loyally", -"loyalty", -"lozenge", -"lozengy", -"lubber", -"lube", -"lubra", -"lubric", -"lubrify", -"lucanid", -"lucarne", -"lucban", -"luce", -"lucence", -"lucency", -"lucent", -"lucern", -"lucerne", -"lucet", -"lucible", -"lucid", -"lucida", -"lucidly", -"lucifee", -"lucific", -"lucigen", -"lucivee", -"luck", -"lucken", -"luckful", -"luckie", -"luckily", -"lucky", -"lucre", -"lucrify", -"lucule", -"lucumia", -"lucy", -"ludden", -"ludibry", -"ludo", -"lue", -"lues", -"luetic", -"lufbery", -"luff", -"lug", -"luge", -"luger", -"luggage", -"luggar", -"lugged", -"lugger", -"luggie", -"lugmark", -"lugsail", -"lugsome", -"lugworm", -"luhinga", -"luigino", -"luke", -"lukely", -"lulab", -"lull", -"lullaby", -"luller", -"lulu", -"lum", -"lumbago", -"lumbang", -"lumbar", -"lumber", -"lumen", -"luminal", -"lumine", -"lummox", -"lummy", -"lump", -"lumper", -"lumpet", -"lumpily", -"lumping", -"lumpish", -"lumpkin", -"lumpman", -"lumpy", -"luna", -"lunacy", -"lunar", -"lunare", -"lunary", -"lunate", -"lunatic", -"lunatum", -"lunch", -"luncher", -"lune", -"lunes", -"lunette", -"lung", -"lunge", -"lunged", -"lunger", -"lungful", -"lungi", -"lungie", -"lungis", -"lungy", -"lunn", -"lunoid", -"lunt", -"lunula", -"lunular", -"lunule", -"lunulet", -"lupe", -"lupeol", -"lupeose", -"lupine", -"lupinin", -"lupis", -"lupoid", -"lupous", -"lupulic", -"lupulin", -"lupulus", -"lupus", -"lura", -"lural", -"lurch", -"lurcher", -"lurdan", -"lure", -"lureful", -"lurer", -"lurg", -"lurid", -"luridly", -"lurk", -"lurker", -"lurky", -"lurrier", -"lurry", -"lush", -"lusher", -"lushly", -"lushy", -"lusk", -"lusky", -"lusory", -"lust", -"luster", -"lustful", -"lustily", -"lustra", -"lustral", -"lustrum", -"lusty", -"lut", -"lutany", -"lute", -"luteal", -"lutecia", -"lutein", -"lutelet", -"luteo", -"luteoma", -"luteous", -"luter", -"luteway", -"lutfisk", -"luthern", -"luthier", -"luting", -"lutist", -"lutose", -"lutrin", -"lutrine", -"lux", -"luxate", -"luxe", -"luxury", -"luxus", -"ly", -"lyam", -"lyard", -"lyceal", -"lyceum", -"lycid", -"lycopin", -"lycopod", -"lycosid", -"lyctid", -"lyddite", -"lydite", -"lye", -"lyery", -"lygaeid", -"lying", -"lyingly", -"lymph", -"lymphad", -"lymphy", -"lyncean", -"lynch", -"lyncher", -"lyncine", -"lynx", -"lyra", -"lyrate", -"lyrated", -"lyraway", -"lyre", -"lyreman", -"lyric", -"lyrical", -"lyrism", -"lyrist", -"lys", -"lysate", -"lyse", -"lysin", -"lysine", -"lysis", -"lysogen", -"lyssa", -"lyssic", -"lytic", -"lytta", -"lyxose", -"m", -"ma", -"maam", -"mabi", -"mabolo", -"mac", -"macabre", -"macaco", -"macadam", -"macan", -"macana", -"macao", -"macaque", -"macaw", -"macco", -"mace", -"maceman", -"macer", -"machan", -"machar", -"machete", -"machi", -"machila", -"machin", -"machine", -"machree", -"macies", -"mack", -"mackins", -"mackle", -"macle", -"macled", -"maco", -"macrame", -"macro", -"macron", -"macuca", -"macula", -"macular", -"macule", -"macuta", -"mad", -"madam", -"madame", -"madcap", -"madden", -"madder", -"madding", -"maddish", -"maddle", -"made", -"madefy", -"madhuca", -"madid", -"madling", -"madly", -"madman", -"madnep", -"madness", -"mado", -"madoqua", -"madrier", -"madrona", -"madship", -"maduro", -"madweed", -"madwort", -"mae", -"maenad", -"maestri", -"maestro", -"maffia", -"maffick", -"maffle", -"mafflin", -"mafic", -"mafoo", -"mafura", -"mag", -"magadis", -"magani", -"magas", -"mage", -"magenta", -"magged", -"maggle", -"maggot", -"maggoty", -"magi", -"magic", -"magical", -"magiric", -"magma", -"magnate", -"magnes", -"magnet", -"magneta", -"magneto", -"magnify", -"magnum", -"magot", -"magpie", -"magpied", -"magsman", -"maguari", -"maguey", -"maha", -"mahaleb", -"mahalla", -"mahant", -"mahar", -"maharao", -"mahatma", -"mahmal", -"mahmudi", -"mahoe", -"maholi", -"mahone", -"mahout", -"mahseer", -"mahua", -"mahuang", -"maid", -"maidan", -"maiden", -"maidish", -"maidism", -"maidkin", -"maidy", -"maiefic", -"maigre", -"maiid", -"mail", -"mailbag", -"mailbox", -"mailed", -"mailer", -"mailie", -"mailman", -"maim", -"maimed", -"maimer", -"maimon", -"main", -"mainly", -"mainour", -"mainpin", -"mains", -"maint", -"maintop", -"maioid", -"maire", -"maize", -"maizer", -"majagua", -"majesty", -"majo", -"majoon", -"major", -"makable", -"make", -"makedom", -"maker", -"makhzan", -"maki", -"making", -"makluk", -"mako", -"makuk", -"mal", -"mala", -"malacia", -"malacon", -"malady", -"malagma", -"malaise", -"malakin", -"malambo", -"malanga", -"malapi", -"malar", -"malaria", -"malarin", -"malate", -"malati", -"malax", -"malduck", -"male", -"malease", -"maleate", -"maleic", -"malella", -"maleo", -"malfed", -"mali", -"malic", -"malice", -"malicho", -"malign", -"malik", -"maline", -"malines", -"malism", -"malison", -"malist", -"malkin", -"mall", -"mallard", -"malleal", -"mallear", -"mallee", -"mallein", -"mallet", -"malleus", -"mallow", -"mallum", -"mallus", -"malm", -"malmsey", -"malmy", -"malo", -"malodor", -"malonic", -"malonyl", -"malouah", -"malpais", -"malt", -"maltase", -"malter", -"maltha", -"malting", -"maltman", -"maltose", -"malty", -"mamba", -"mambo", -"mamma", -"mammal", -"mammary", -"mammate", -"mammee", -"mammer", -"mammock", -"mammon", -"mammoth", -"mammula", -"mammy", -"mamo", -"man", -"mana", -"manacle", -"manage", -"managee", -"manager", -"manaism", -"manakin", -"manal", -"manas", -"manatee", -"manavel", -"manbird", -"manbot", -"manche", -"manchet", -"mancono", -"mancus", -"mand", -"mandala", -"mandant", -"mandate", -"mandil", -"mandola", -"mandom", -"mandora", -"mandore", -"mandra", -"mandrel", -"mandrin", -"mandua", -"mandyas", -"mane", -"maned", -"manege", -"manei", -"manent", -"manes", -"maness", -"maney", -"manful", -"mang", -"manga", -"mangal", -"mange", -"mangeao", -"mangel", -"manger", -"mangi", -"mangily", -"mangle", -"mangler", -"mango", -"mangona", -"mangue", -"mangy", -"manhead", -"manhole", -"manhood", -"mani", -"mania", -"maniac", -"manic", -"manid", -"manify", -"manikin", -"manila", -"manilla", -"manille", -"manioc", -"maniple", -"manism", -"manist", -"manito", -"maniu", -"manjak", -"mank", -"mankin", -"mankind", -"manless", -"manlet", -"manlike", -"manlily", -"manling", -"manly", -"manna", -"mannan", -"manner", -"manners", -"manness", -"mannide", -"mannie", -"mannify", -"manning", -"mannish", -"mannite", -"mannose", -"manny", -"mano", -"manoc", -"manomin", -"manor", -"manque", -"manred", -"manrent", -"manroot", -"manrope", -"mansard", -"manse", -"manship", -"mansion", -"manso", -"mant", -"manta", -"mantal", -"manteau", -"mantel", -"manter", -"mantes", -"mantic", -"mantid", -"mantis", -"mantle", -"mantled", -"mantlet", -"manto", -"mantoid", -"mantra", -"mantrap", -"mantua", -"manual", -"manuao", -"manuka", -"manul", -"manuma", -"manumea", -"manumit", -"manure", -"manurer", -"manus", -"manward", -"manway", -"manweed", -"manwise", -"many", -"manzana", -"manzil", -"mao", -"maomao", -"map", -"mapach", -"mapau", -"mapland", -"maple", -"mapo", -"mapper", -"mappist", -"mappy", -"mapwise", -"maqui", -"maquis", -"mar", -"marabou", -"maraca", -"maracan", -"marae", -"maral", -"marang", -"marara", -"mararie", -"marasca", -"maraud", -"marble", -"marbled", -"marbler", -"marbles", -"marbly", -"marc", -"marcel", -"march", -"marcher", -"marcid", -"marco", -"marconi", -"marcor", -"mardy", -"mare", -"maremma", -"marengo", -"marfire", -"margay", -"marge", -"margent", -"margin", -"margosa", -"marhala", -"maria", -"marid", -"marimba", -"marina", -"marine", -"mariner", -"mariola", -"maris", -"marish", -"marital", -"mark", -"marka", -"marked", -"marker", -"market", -"markhor", -"marking", -"markka", -"markman", -"markup", -"marl", -"marled", -"marler", -"marli", -"marlin", -"marline", -"marlite", -"marlock", -"marlpit", -"marly", -"marm", -"marmit", -"marmite", -"marmose", -"marmot", -"maro", -"marok", -"maroon", -"marplot", -"marque", -"marquee", -"marquis", -"marrano", -"marree", -"marrer", -"married", -"marrier", -"marron", -"marrot", -"marrow", -"marrowy", -"marry", -"marryer", -"marsh", -"marshal", -"marshy", -"marsoon", -"mart", -"martel", -"marten", -"martext", -"martial", -"martin", -"martite", -"martlet", -"martyr", -"martyry", -"maru", -"marvel", -"marver", -"mary", -"marybud", -"mas", -"masa", -"mascara", -"mascled", -"mascot", -"masculy", -"masdeu", -"mash", -"masha", -"mashal", -"masher", -"mashie", -"mashing", -"mashman", -"mashru", -"mashy", -"masjid", -"mask", -"masked", -"masker", -"maskoid", -"maslin", -"mason", -"masoned", -"masoner", -"masonic", -"masonry", -"masooka", -"masoola", -"masque", -"masquer", -"mass", -"massa", -"massage", -"masse", -"massel", -"masser", -"masseur", -"massier", -"massif", -"massily", -"massive", -"massoy", -"massula", -"massy", -"mast", -"mastaba", -"mastage", -"mastax", -"masted", -"master", -"mastery", -"mastful", -"mastic", -"mastiff", -"masting", -"mastman", -"mastoid", -"masty", -"masu", -"mat", -"mataco", -"matador", -"matai", -"matalan", -"matanza", -"matapan", -"matapi", -"matara", -"matax", -"match", -"matcher", -"matchy", -"mate", -"mately", -"mater", -"matey", -"math", -"mathes", -"matico", -"matin", -"matinal", -"matinee", -"mating", -"matins", -"matipo", -"matka", -"matless", -"matlow", -"matra", -"matral", -"matrass", -"matreed", -"matric", -"matris", -"matrix", -"matron", -"matross", -"matsu", -"matsuri", -"matta", -"mattaro", -"matte", -"matted", -"matter", -"mattery", -"matti", -"matting", -"mattock", -"mattoid", -"mattoir", -"mature", -"maturer", -"matweed", -"maty", -"matzo", -"matzoon", -"matzos", -"matzoth", -"mau", -"maud", -"maudle", -"maudlin", -"mauger", -"maugh", -"maul", -"mauler", -"mauley", -"mauling", -"maumet", -"maun", -"maund", -"maunder", -"maundy", -"maunge", -"mauther", -"mauve", -"mauvine", -"maux", -"mavis", -"maw", -"mawk", -"mawkish", -"mawky", -"mawp", -"maxilla", -"maxim", -"maxima", -"maximal", -"maximed", -"maximum", -"maximus", -"maxixe", -"maxwell", -"may", -"maya", -"maybe", -"maybush", -"maycock", -"mayday", -"mayfish", -"mayhap", -"mayhem", -"maynt", -"mayor", -"mayoral", -"maypop", -"maysin", -"mayten", -"mayweed", -"maza", -"mazame", -"mazard", -"maze", -"mazed", -"mazedly", -"mazeful", -"mazer", -"mazic", -"mazily", -"mazuca", -"mazuma", -"mazurka", -"mazut", -"mazy", -"mazzard", -"mbalolo", -"mbori", -"me", -"meable", -"mead", -"meader", -"meadow", -"meadowy", -"meager", -"meagre", -"meak", -"meal", -"mealer", -"mealies", -"mealily", -"mealman", -"mealy", -"mean", -"meander", -"meaned", -"meaner", -"meaning", -"meanish", -"meanly", -"meant", -"mease", -"measle", -"measled", -"measles", -"measly", -"measure", -"meat", -"meatal", -"meated", -"meatily", -"meatman", -"meatus", -"meaty", -"mecate", -"mecon", -"meconic", -"meconin", -"medal", -"medaled", -"medalet", -"meddle", -"meddler", -"media", -"mediacy", -"mediad", -"medial", -"median", -"mediant", -"mediate", -"medic", -"medical", -"medico", -"mediety", -"medimn", -"medimno", -"medino", -"medio", -"medium", -"medius", -"medlar", -"medley", -"medrick", -"medulla", -"medusal", -"medusan", -"meebos", -"meece", -"meed", -"meek", -"meeken", -"meekly", -"meered", -"meerkat", -"meese", -"meet", -"meeten", -"meeter", -"meeting", -"meetly", -"megabar", -"megaerg", -"megafog", -"megapod", -"megaron", -"megaton", -"megerg", -"megilp", -"megmho", -"megohm", -"megrim", -"mehalla", -"mehari", -"mehtar", -"meile", -"mein", -"meinie", -"meio", -"meiobar", -"meiosis", -"meiotic", -"meith", -"mel", -"mela", -"melada", -"melagra", -"melam", -"melamed", -"melange", -"melanic", -"melanin", -"melano", -"melasma", -"melch", -"meld", -"melder", -"meldrop", -"mele", -"melee", -"melena", -"melene", -"melenic", -"melic", -"melilot", -"meline", -"melisma", -"melitis", -"mell", -"mellate", -"mellay", -"meller", -"mellit", -"mellite", -"mellon", -"mellow", -"mellowy", -"melodia", -"melodic", -"melody", -"meloe", -"meloid", -"melon", -"melonry", -"melos", -"melosa", -"melt", -"meltage", -"melted", -"melter", -"melters", -"melting", -"melton", -"mem", -"member", -"membral", -"memento", -"meminna", -"memo", -"memoir", -"memoria", -"memory", -"men", -"menace", -"menacer", -"menacme", -"menage", -"menald", -"mend", -"mendee", -"mender", -"mending", -"mendole", -"mends", -"menfolk", -"meng", -"menhir", -"menial", -"meninx", -"menkind", -"mennom", -"mensa", -"mensal", -"mense", -"menses", -"mensk", -"mensual", -"mental", -"mentary", -"menthol", -"menthyl", -"mention", -"mentor", -"mentum", -"menu", -"meny", -"menyie", -"menzie", -"merbaby", -"mercal", -"mercer", -"mercery", -"merch", -"merchet", -"mercy", -"mere", -"merel", -"merely", -"merfold", -"merfolk", -"merge", -"merger", -"mergh", -"meriah", -"merice", -"meril", -"merism", -"merist", -"merit", -"merited", -"meriter", -"merk", -"merkhet", -"merkin", -"merl", -"merle", -"merlin", -"merlon", -"mermaid", -"merman", -"mero", -"merop", -"meropia", -"meros", -"merrily", -"merrow", -"merry", -"merse", -"mesa", -"mesad", -"mesail", -"mesal", -"mesally", -"mesange", -"mesarch", -"mescal", -"mese", -"mesem", -"mesenna", -"mesh", -"meshed", -"meshy", -"mesiad", -"mesial", -"mesian", -"mesic", -"mesilla", -"mesion", -"mesityl", -"mesne", -"meso", -"mesobar", -"mesode", -"mesodic", -"mesole", -"meson", -"mesonic", -"mesopic", -"mespil", -"mess", -"message", -"messan", -"messe", -"messer", -"messet", -"messily", -"messin", -"messing", -"messman", -"messor", -"messrs", -"messtin", -"messy", -"mestee", -"mester", -"mestiza", -"mestizo", -"mestome", -"met", -"meta", -"metad", -"metage", -"metal", -"metaler", -"metamer", -"metanym", -"metate", -"metayer", -"mete", -"metel", -"meteor", -"meter", -"methane", -"methene", -"mether", -"methid", -"methide", -"methine", -"method", -"methyl", -"metic", -"metier", -"metis", -"metochy", -"metonym", -"metope", -"metopic", -"metopon", -"metra", -"metreta", -"metrete", -"metria", -"metric", -"metrics", -"metrify", -"metrist", -"mettar", -"mettle", -"mettled", -"metusia", -"metze", -"meuse", -"meute", -"mew", -"meward", -"mewer", -"mewl", -"mewler", -"mezcal", -"mezuzah", -"mezzo", -"mho", -"mi", -"miamia", -"mian", -"miaow", -"miaower", -"mias", -"miasm", -"miasma", -"miasmal", -"miasmic", -"miaul", -"miauler", -"mib", -"mica", -"micate", -"mice", -"micelle", -"miche", -"micher", -"miching", -"micht", -"mick", -"mickle", -"mico", -"micrify", -"micro", -"microbe", -"microhm", -"micron", -"miction", -"mid", -"midday", -"midden", -"middle", -"middler", -"middy", -"mide", -"midge", -"midget", -"midgety", -"midgy", -"midiron", -"midland", -"midleg", -"midmain", -"midmorn", -"midmost", -"midnoon", -"midpit", -"midrash", -"midrib", -"midriff", -"mids", -"midship", -"midst", -"midtap", -"midvein", -"midward", -"midway", -"midweek", -"midwife", -"midwise", -"midyear", -"mien", -"miff", -"miffy", -"mig", -"might", -"mightnt", -"mighty", -"miglio", -"mignon", -"migrant", -"migrate", -"mihrab", -"mijl", -"mikado", -"mike", -"mikie", -"mil", -"mila", -"milady", -"milch", -"milcher", -"milchy", -"mild", -"milden", -"milder", -"mildew", -"mildewy", -"mildish", -"mildly", -"mile", -"mileage", -"miler", -"mileway", -"milfoil", -"milha", -"miliary", -"milieu", -"militia", -"milium", -"milk", -"milken", -"milker", -"milkily", -"milking", -"milkman", -"milksop", -"milky", -"mill", -"milla", -"millage", -"milldam", -"mille", -"milled", -"miller", -"millet", -"millful", -"milliad", -"millile", -"milline", -"milling", -"million", -"millman", -"milner", -"milo", -"milord", -"milpa", -"milreis", -"milsey", -"milsie", -"milt", -"milter", -"milty", -"milvine", -"mim", -"mima", -"mimbar", -"mimble", -"mime", -"mimeo", -"mimer", -"mimesis", -"mimetic", -"mimic", -"mimical", -"mimicry", -"mimine", -"mimly", -"mimmest", -"mimmock", -"mimmood", -"mimmoud", -"mimosis", -"mimp", -"mimsey", -"min", -"mina", -"minable", -"minar", -"minaret", -"minaway", -"mince", -"mincer", -"mincing", -"mind", -"minded", -"minder", -"mindful", -"minding", -"mine", -"miner", -"mineral", -"minery", -"mines", -"minette", -"ming", -"minge", -"mingle", -"mingler", -"mingy", -"minhag", -"minhah", -"miniate", -"minibus", -"minicam", -"minify", -"minikin", -"minim", -"minima", -"minimal", -"minimum", -"minimus", -"mining", -"minion", -"minish", -"minium", -"miniver", -"minivet", -"mink", -"minkery", -"minkish", -"minnie", -"minning", -"minnow", -"minny", -"mino", -"minoize", -"minor", -"minot", -"minster", -"mint", -"mintage", -"minter", -"mintman", -"minty", -"minuend", -"minuet", -"minus", -"minute", -"minuter", -"minutia", -"minx", -"minxish", -"miny", -"minyan", -"miqra", -"mir", -"mirach", -"miracle", -"mirador", -"mirage", -"miragy", -"mirate", -"mirbane", -"mird", -"mirdaha", -"mire", -"mirid", -"mirific", -"mirish", -"mirk", -"miro", -"mirror", -"mirrory", -"mirth", -"miry", -"mirza", -"misact", -"misadd", -"misaim", -"misally", -"misbias", -"misbill", -"misbind", -"misbode", -"misborn", -"misbusy", -"miscall", -"miscast", -"mischio", -"miscoin", -"miscook", -"miscrop", -"miscue", -"miscut", -"misdate", -"misdaub", -"misdeal", -"misdeed", -"misdeem", -"misdiet", -"misdo", -"misdoer", -"misdraw", -"mise", -"misease", -"misedit", -"miser", -"miserly", -"misery", -"misfare", -"misfile", -"misfire", -"misfit", -"misfond", -"misform", -"misgive", -"misgo", -"misgrow", -"mishap", -"mishmee", -"misjoin", -"miskeep", -"misken", -"miskill", -"misknow", -"misky", -"mislay", -"mislead", -"mislear", -"misled", -"mislest", -"mislike", -"mislive", -"mismade", -"mismake", -"mismate", -"mismove", -"misname", -"misobey", -"mispage", -"mispart", -"mispay", -"mispick", -"misplay", -"misput", -"misrate", -"misread", -"misrule", -"miss", -"missal", -"missay", -"misseem", -"missel", -"misset", -"missile", -"missing", -"mission", -"missis", -"missish", -"missive", -"misstay", -"misstep", -"missy", -"mist", -"mistake", -"mistbow", -"misted", -"mistell", -"mistend", -"mister", -"misterm", -"mistful", -"mistic", -"mistide", -"mistify", -"mistily", -"mistime", -"mistle", -"mistone", -"mistook", -"mistral", -"mistry", -"misturn", -"misty", -"misura", -"misuse", -"misuser", -"miswed", -"miswish", -"misword", -"misyoke", -"mite", -"miter", -"mitered", -"miterer", -"mitis", -"mitome", -"mitosis", -"mitotic", -"mitra", -"mitral", -"mitrate", -"mitre", -"mitrer", -"mitt", -"mitten", -"mitty", -"mity", -"miurus", -"mix", -"mixable", -"mixed", -"mixedly", -"mixen", -"mixer", -"mixhill", -"mixible", -"mixite", -"mixtion", -"mixture", -"mixy", -"mizmaze", -"mizzen", -"mizzle", -"mizzler", -"mizzly", -"mizzy", -"mneme", -"mnemic", -"mnesic", -"mnestic", -"mnioid", -"mo", -"moan", -"moanful", -"moaning", -"moat", -"mob", -"mobable", -"mobber", -"mobbish", -"mobbism", -"mobbist", -"mobby", -"mobcap", -"mobed", -"mobile", -"moble", -"moblike", -"mobship", -"mobsman", -"mobster", -"mocha", -"mochras", -"mock", -"mockado", -"mocker", -"mockery", -"mockful", -"mocmain", -"mocuck", -"modal", -"modally", -"mode", -"model", -"modeler", -"modena", -"modern", -"modest", -"modesty", -"modicum", -"modify", -"modish", -"modist", -"modiste", -"modius", -"modular", -"module", -"modulo", -"modulus", -"moellon", -"mofette", -"moff", -"mog", -"mogador", -"mogdad", -"moggan", -"moggy", -"mogo", -"moguey", -"moha", -"mohabat", -"mohair", -"mohar", -"mohel", -"moho", -"mohr", -"mohur", -"moider", -"moidore", -"moieter", -"moiety", -"moil", -"moiler", -"moiles", -"moiley", -"moiling", -"moineau", -"moio", -"moire", -"moise", -"moist", -"moisten", -"moistly", -"moisty", -"moit", -"moity", -"mojarra", -"mojo", -"moke", -"moki", -"moko", -"moksha", -"mokum", -"moky", -"mola", -"molal", -"molar", -"molary", -"molassy", -"molave", -"mold", -"molder", -"moldery", -"molding", -"moldy", -"mole", -"moleism", -"moler", -"molest", -"molimen", -"moline", -"molka", -"molland", -"molle", -"mollie", -"mollify", -"mollusk", -"molly", -"molman", -"moloid", -"moloker", -"molompi", -"molosse", -"molpe", -"molt", -"molten", -"molter", -"moly", -"mombin", -"momble", -"mome", -"moment", -"momenta", -"momism", -"momme", -"mommet", -"mommy", -"momo", -"mon", -"mona", -"monad", -"monadic", -"monaene", -"monal", -"monarch", -"monas", -"monase", -"monaxon", -"mone", -"monel", -"monepic", -"moner", -"moneral", -"moneran", -"moneric", -"moneron", -"monesia", -"money", -"moneyed", -"moneyer", -"mong", -"monger", -"mongery", -"mongler", -"mongrel", -"mongst", -"monial", -"moniker", -"monism", -"monist", -"monitor", -"monk", -"monkdom", -"monkery", -"monkess", -"monkey", -"monkish", -"monkism", -"monkly", -"monny", -"mono", -"monoazo", -"monocle", -"monocot", -"monodic", -"monody", -"monoid", -"monomer", -"mononch", -"monont", -"mononym", -"monose", -"monotic", -"monsoon", -"monster", -"montage", -"montana", -"montane", -"montant", -"monte", -"montem", -"month", -"monthly", -"monthon", -"montjoy", -"monton", -"monture", -"moo", -"mooch", -"moocha", -"moocher", -"mood", -"mooder", -"moodily", -"moodish", -"moodle", -"moody", -"mooing", -"mool", -"moolet", -"mools", -"moolum", -"moon", -"moonack", -"mooned", -"mooner", -"moonery", -"mooneye", -"moonily", -"mooning", -"moonish", -"moonite", -"moonja", -"moonjah", -"moonlet", -"moonlit", -"moonman", -"moonset", -"moonway", -"moony", -"moop", -"moor", -"moorage", -"mooring", -"moorish", -"moorman", -"moorn", -"moorpan", -"moors", -"moorup", -"moory", -"moosa", -"moose", -"moosey", -"moost", -"moot", -"mooter", -"mooth", -"mooting", -"mootman", -"mop", -"mopane", -"mope", -"moper", -"moph", -"mophead", -"moping", -"mopish", -"mopla", -"mopper", -"moppet", -"moppy", -"mopsy", -"mopus", -"mor", -"mora", -"moraine", -"moral", -"morale", -"morally", -"morals", -"morass", -"morassy", -"morat", -"morate", -"moray", -"morbid", -"morbify", -"mordant", -"mordent", -"mordore", -"more", -"moreen", -"moreish", -"morel", -"morella", -"morello", -"mores", -"morfrey", -"morg", -"morga", -"morgan", -"morgay", -"morgen", -"morglay", -"morgue", -"moric", -"moriche", -"morin", -"morinel", -"morion", -"morkin", -"morlop", -"mormaor", -"mormo", -"mormon", -"mormyr", -"mormyre", -"morn", -"morne", -"morned", -"morning", -"moro", -"moroc", -"morocco", -"moron", -"moroncy", -"morong", -"moronic", -"moronry", -"morose", -"morosis", -"morph", -"morphea", -"morphew", -"morphia", -"morphic", -"morphon", -"morris", -"morrow", -"morsal", -"morse", -"morsel", -"morsing", -"morsure", -"mort", -"mortal", -"mortar", -"mortary", -"morth", -"mortier", -"mortify", -"mortise", -"morula", -"morular", -"morule", -"morvin", -"morwong", -"mosaic", -"mosaist", -"mosette", -"mosey", -"mosker", -"mosque", -"moss", -"mossed", -"mosser", -"mossery", -"mossful", -"mossy", -"most", -"moste", -"mostly", -"mot", -"mote", -"moted", -"motel", -"moter", -"motet", -"motey", -"moth", -"mothed", -"mother", -"mothery", -"mothy", -"motif", -"motific", -"motile", -"motion", -"motive", -"motley", -"motmot", -"motor", -"motored", -"motoric", -"motory", -"mott", -"motte", -"mottle", -"mottled", -"mottler", -"motto", -"mottoed", -"motyka", -"mou", -"mouche", -"moud", -"moudie", -"moudy", -"mouflon", -"mouille", -"moujik", -"moul", -"mould", -"moulded", -"moule", -"moulin", -"mouls", -"moulter", -"mouly", -"mound", -"moundy", -"mount", -"mounted", -"mounter", -"moup", -"mourn", -"mourner", -"mouse", -"mouser", -"mousery", -"mousey", -"mousily", -"mousing", -"mousle", -"mousmee", -"mousse", -"moustoc", -"mousy", -"mout", -"moutan", -"mouth", -"mouthed", -"mouther", -"mouthy", -"mouton", -"mouzah", -"movable", -"movably", -"movant", -"move", -"mover", -"movie", -"moving", -"mow", -"mowable", -"mowana", -"mowburn", -"mowch", -"mowcht", -"mower", -"mowha", -"mowie", -"mowing", -"mowland", -"mown", -"mowra", -"mowrah", -"mowse", -"mowt", -"mowth", -"moxa", -"moy", -"moyen", -"moyenne", -"moyite", -"moyle", -"moyo", -"mozing", -"mpret", -"mu", -"muang", -"mubarat", -"mucago", -"mucaro", -"mucedin", -"much", -"muchly", -"mucic", -"mucid", -"mucific", -"mucigen", -"mucin", -"muck", -"mucker", -"mucket", -"muckite", -"muckle", -"muckman", -"muckna", -"mucksy", -"mucky", -"mucluc", -"mucoid", -"muconic", -"mucopus", -"mucor", -"mucosa", -"mucosal", -"mucose", -"mucous", -"mucro", -"mucus", -"mucusin", -"mud", -"mudar", -"mudbank", -"mudcap", -"mudd", -"mudde", -"mudden", -"muddify", -"muddily", -"mudding", -"muddish", -"muddle", -"muddler", -"muddy", -"mudee", -"mudfish", -"mudflow", -"mudhead", -"mudhole", -"mudir", -"mudiria", -"mudland", -"mudlark", -"mudless", -"mudra", -"mudsill", -"mudweed", -"mudwort", -"muermo", -"muezzin", -"muff", -"muffed", -"muffet", -"muffin", -"muffish", -"muffle", -"muffled", -"muffler", -"mufflin", -"muffy", -"mufti", -"mufty", -"mug", -"muga", -"mugful", -"mugg", -"mugger", -"mugget", -"muggily", -"muggins", -"muggish", -"muggles", -"muggy", -"mugient", -"mugweed", -"mugwort", -"mugwump", -"muid", -"muir", -"muist", -"mukluk", -"muktar", -"mukti", -"mulatta", -"mulatto", -"mulch", -"mulcher", -"mulct", -"mulder", -"mule", -"muleman", -"muleta", -"muletta", -"muley", -"mulga", -"mulier", -"mulish", -"mulism", -"mulita", -"mulk", -"mull", -"mulla", -"mullah", -"mullar", -"mullein", -"muller", -"mullet", -"mullets", -"mulley", -"mullid", -"mullion", -"mullite", -"mullock", -"mulloid", -"mulmul", -"mulse", -"mulsify", -"mult", -"multum", -"multure", -"mum", -"mumble", -"mumbler", -"mummer", -"mummery", -"mummick", -"mummied", -"mummify", -"mumming", -"mummy", -"mumness", -"mump", -"mumper", -"mumpish", -"mumps", -"mun", -"munch", -"muncher", -"munchet", -"mund", -"mundane", -"mundic", -"mundify", -"mundil", -"mundle", -"mung", -"munga", -"munge", -"mungey", -"mungo", -"mungofa", -"munguba", -"mungy", -"munific", -"munity", -"munj", -"munjeet", -"munnion", -"munshi", -"munt", -"muntin", -"muntjac", -"mura", -"murage", -"mural", -"muraled", -"murally", -"murchy", -"murder", -"murdrum", -"mure", -"murex", -"murexan", -"murga", -"murgavi", -"murgeon", -"muriate", -"muricid", -"murid", -"murine", -"murinus", -"muriti", -"murium", -"murk", -"murkily", -"murkish", -"murkly", -"murky", -"murlin", -"murly", -"murmur", -"murphy", -"murra", -"murrain", -"murre", -"murrey", -"murrina", -"murshid", -"muruxi", -"murva", -"murza", -"musal", -"musang", -"musar", -"muscade", -"muscat", -"muscid", -"muscle", -"muscled", -"muscly", -"muscoid", -"muscone", -"muscose", -"muscot", -"muscovy", -"muscule", -"muse", -"mused", -"museful", -"museist", -"muser", -"musery", -"musette", -"museum", -"mush", -"musha", -"mushaa", -"mushed", -"musher", -"mushily", -"mushla", -"mushru", -"mushy", -"music", -"musical", -"musico", -"musie", -"musily", -"musimon", -"musing", -"musk", -"muskat", -"muskeg", -"musket", -"muskie", -"muskish", -"muskrat", -"musky", -"muslin", -"musnud", -"musquaw", -"musrol", -"muss", -"mussal", -"mussel", -"mussily", -"mussuk", -"mussy", -"must", -"mustang", -"mustard", -"mustee", -"muster", -"mustify", -"mustily", -"mustnt", -"musty", -"muta", -"mutable", -"mutably", -"mutage", -"mutant", -"mutase", -"mutate", -"mutch", -"mute", -"mutedly", -"mutely", -"muth", -"mutic", -"mutiny", -"mutism", -"mutist", -"mutive", -"mutsje", -"mutt", -"mutter", -"mutton", -"muttony", -"mutual", -"mutuary", -"mutule", -"mutuum", -"mux", -"muyusa", -"muzhik", -"muzz", -"muzzily", -"muzzle", -"muzzler", -"muzzy", -"my", -"myal", -"myalgia", -"myalgic", -"myalism", -"myall", -"myarian", -"myatony", -"mycele", -"mycelia", -"mycoid", -"mycose", -"mycosin", -"mycosis", -"mycotic", -"mydine", -"myelic", -"myelin", -"myeloic", -"myeloid", -"myeloma", -"myelon", -"mygale", -"mygalid", -"myiasis", -"myiosis", -"myitis", -"mykiss", -"mymarid", -"myna", -"myocele", -"myocyte", -"myogen", -"myogram", -"myoid", -"myology", -"myoma", -"myomere", -"myoneme", -"myope", -"myophan", -"myopia", -"myopic", -"myops", -"myopy", -"myosin", -"myosis", -"myosote", -"myotic", -"myotome", -"myotomy", -"myotony", -"myowun", -"myoxine", -"myrcene", -"myrcia", -"myriad", -"myriare", -"myrica", -"myricin", -"myricyl", -"myringa", -"myron", -"myronic", -"myrosin", -"myrrh", -"myrrhed", -"myrrhic", -"myrrhol", -"myrrhy", -"myrtal", -"myrtle", -"myrtol", -"mysel", -"myself", -"mysell", -"mysid", -"mysoid", -"mysost", -"myst", -"mystax", -"mystery", -"mystes", -"mystic", -"mystify", -"myth", -"mythify", -"mythism", -"mythist", -"mythize", -"mythos", -"mythus", -"mytilid", -"myxa", -"myxemia", -"myxo", -"myxoid", -"myxoma", -"myxopod", -"myzont", -"n", -"na", -"naa", -"naam", -"nab", -"nabak", -"nabber", -"nabk", -"nabla", -"nable", -"nabob", -"nabobry", -"nabs", -"nacarat", -"nace", -"nacelle", -"nach", -"nachani", -"nacket", -"nacre", -"nacred", -"nacrine", -"nacrite", -"nacrous", -"nacry", -"nadder", -"nadir", -"nadiral", -"nae", -"naebody", -"naegate", -"nael", -"naether", -"nag", -"naga", -"nagaika", -"nagana", -"nagara", -"nagger", -"naggin", -"nagging", -"naggish", -"naggle", -"naggly", -"naggy", -"naght", -"nagmaal", -"nagman", -"nagnag", -"nagnail", -"nagor", -"nagsman", -"nagster", -"nagual", -"naiad", -"naiant", -"naid", -"naif", -"naifly", -"naig", -"naigie", -"naik", -"nail", -"nailbin", -"nailer", -"nailery", -"nailing", -"nailrod", -"naily", -"nain", -"nainsel", -"naio", -"naipkin", -"nairy", -"nais", -"naish", -"naither", -"naive", -"naively", -"naivete", -"naivety", -"nak", -"nake", -"naked", -"nakedly", -"naker", -"nakhod", -"nakhoda", -"nako", -"nakong", -"nakoo", -"nallah", -"nam", -"namable", -"namaqua", -"namaz", -"namda", -"name", -"namely", -"namer", -"naming", -"nammad", -"nan", -"nana", -"nancy", -"nandi", -"nandine", -"nandow", -"nandu", -"nane", -"nanes", -"nanga", -"nanism", -"nankeen", -"nankin", -"nanny", -"nanoid", -"nanpie", -"nant", -"nantle", -"naology", -"naos", -"nap", -"napa", -"napal", -"napalm", -"nape", -"napead", -"naperer", -"napery", -"naphtha", -"naphtho", -"naphtol", -"napkin", -"napless", -"napoo", -"nappe", -"napped", -"napper", -"napping", -"nappy", -"napron", -"napu", -"nar", -"narcism", -"narcist", -"narcoma", -"narcose", -"narcous", -"nard", -"nardine", -"nardoo", -"nares", -"nargil", -"narial", -"naric", -"narica", -"narine", -"nark", -"narky", -"narr", -"narra", -"narras", -"narrate", -"narrow", -"narrowy", -"narthex", -"narwhal", -"nary", -"nasab", -"nasal", -"nasalis", -"nasally", -"nasard", -"nascent", -"nasch", -"nash", -"nashgab", -"nashgob", -"nasi", -"nasial", -"nasion", -"nasitis", -"nasrol", -"nast", -"nastic", -"nastika", -"nastily", -"nasty", -"nasus", -"nasute", -"nasutus", -"nat", -"nataka", -"natal", -"natals", -"natant", -"natator", -"natch", -"nates", -"nathe", -"nather", -"nation", -"native", -"natr", -"natrium", -"natron", -"natter", -"nattily", -"nattle", -"natty", -"natuary", -"natural", -"nature", -"naucrar", -"nauger", -"naught", -"naughty", -"naumk", -"naunt", -"nauntle", -"nausea", -"naut", -"nautch", -"nauther", -"nautic", -"nautics", -"naval", -"navally", -"navar", -"navarch", -"nave", -"navel", -"naveled", -"navet", -"navette", -"navew", -"navite", -"navvy", -"navy", -"naw", -"nawab", -"nawt", -"nay", -"nayaur", -"naysay", -"nayward", -"nayword", -"naze", -"nazim", -"nazir", -"ne", -"nea", -"neal", -"neanic", -"neap", -"neaped", -"nearby", -"nearest", -"nearish", -"nearly", -"neat", -"neaten", -"neath", -"neatify", -"neatly", -"neb", -"neback", -"nebbed", -"nebbuck", -"nebbuk", -"nebby", -"nebel", -"nebris", -"nebula", -"nebulae", -"nebular", -"nebule", -"neck", -"neckar", -"necked", -"necker", -"neckful", -"necking", -"necklet", -"necktie", -"necrose", -"nectar", -"nectary", -"nedder", -"neddy", -"nee", -"neebor", -"neebour", -"need", -"needer", -"needful", -"needham", -"needily", -"needing", -"needle", -"needled", -"needler", -"needles", -"needly", -"needs", -"needy", -"neeger", -"neeld", -"neele", -"neem", -"neep", -"neepour", -"neer", -"neese", -"neet", -"neetup", -"neeze", -"nef", -"nefast", -"neffy", -"neftgil", -"negate", -"negator", -"neger", -"neglect", -"negrine", -"negro", -"negus", -"nei", -"neif", -"neigh", -"neigher", -"neiper", -"neist", -"neither", -"nekton", -"nelson", -"nema", -"nematic", -"nemeses", -"nemesic", -"nemoral", -"nenta", -"neo", -"neocyte", -"neogamy", -"neolith", -"neology", -"neon", -"neonate", -"neorama", -"neossin", -"neoteny", -"neotype", -"neoza", -"nep", -"neper", -"nephele", -"nephesh", -"nephew", -"nephria", -"nephric", -"nephron", -"nephros", -"nepman", -"nepotal", -"nepote", -"nepotic", -"nereite", -"nerine", -"neritic", -"nerval", -"nervate", -"nerve", -"nerver", -"nervid", -"nervily", -"nervine", -"nerving", -"nervish", -"nervism", -"nervose", -"nervous", -"nervule", -"nervure", -"nervy", -"nese", -"nesh", -"neshly", -"nesiote", -"ness", -"nest", -"nestage", -"nester", -"nestful", -"nestle", -"nestler", -"nesty", -"net", -"netball", -"netbush", -"netcha", -"nete", -"neter", -"netful", -"neth", -"nether", -"neti", -"netleaf", -"netlike", -"netman", -"netop", -"netsman", -"netsuke", -"netted", -"netter", -"netting", -"nettle", -"nettler", -"nettly", -"netty", -"netwise", -"network", -"neuma", -"neume", -"neumic", -"neurad", -"neural", -"neurale", -"neuric", -"neurin", -"neurine", -"neurism", -"neurite", -"neuroid", -"neuroma", -"neuron", -"neurone", -"neurula", -"neuter", -"neutral", -"neutron", -"neve", -"nevel", -"never", -"nevo", -"nevoid", -"nevoy", -"nevus", -"new", -"newcal", -"newcome", -"newel", -"newelty", -"newing", -"newings", -"newish", -"newly", -"newness", -"news", -"newsboy", -"newsful", -"newsman", -"newsy", -"newt", -"newtake", -"newton", -"nexal", -"next", -"nextly", -"nexum", -"nexus", -"neyanda", -"ngai", -"ngaio", -"ngapi", -"ni", -"niacin", -"niata", -"nib", -"nibbana", -"nibbed", -"nibber", -"nibble", -"nibbler", -"nibby", -"niblick", -"niblike", -"nibong", -"nibs", -"nibsome", -"nice", -"niceish", -"nicely", -"nicety", -"niche", -"nicher", -"nick", -"nickel", -"nicker", -"nickey", -"nicking", -"nickle", -"nicky", -"nicolo", -"nicotia", -"nicotic", -"nictate", -"nid", -"nidal", -"nidana", -"niddick", -"niddle", -"nide", -"nidge", -"nidget", -"nidgety", -"nidi", -"nidify", -"niding", -"nidor", -"nidulus", -"nidus", -"niece", -"nielled", -"niello", -"niepa", -"nieve", -"nieveta", -"nife", -"niffer", -"nific", -"nifle", -"nifling", -"nifty", -"nig", -"niggard", -"nigger", -"niggery", -"niggle", -"niggler", -"niggly", -"nigh", -"nighly", -"night", -"nighted", -"nightie", -"nightly", -"nights", -"nignay", -"nignye", -"nigori", -"nigre", -"nigrify", -"nigrine", -"nigrous", -"nigua", -"nikau", -"nil", -"nilgai", -"nim", -"nimb", -"nimbed", -"nimbi", -"nimble", -"nimbly", -"nimbose", -"nimbus", -"nimiety", -"niminy", -"nimious", -"nimmer", -"nimshi", -"nincom", -"nine", -"ninepin", -"nineted", -"ninety", -"ninny", -"ninon", -"ninth", -"ninthly", -"nintu", -"ninut", -"niobate", -"niobic", -"niobite", -"niobium", -"niobous", -"niog", -"niota", -"nip", -"nipa", -"nipper", -"nippers", -"nippily", -"nipping", -"nipple", -"nippy", -"nipter", -"nirles", -"nirvana", -"nisei", -"nishiki", -"nisnas", -"nispero", -"nisse", -"nisus", -"nit", -"nitch", -"nitency", -"niter", -"nitered", -"nither", -"nithing", -"nitid", -"nito", -"niton", -"nitrate", -"nitric", -"nitride", -"nitrify", -"nitrile", -"nitrite", -"nitro", -"nitrous", -"nitryl", -"nitter", -"nitty", -"nitwit", -"nival", -"niveous", -"nix", -"nixie", -"niyoga", -"nizam", -"nizamut", -"nizy", -"njave", -"no", -"noa", -"nob", -"nobber", -"nobbily", -"nobble", -"nobbler", -"nobbut", -"nobby", -"noble", -"nobley", -"nobly", -"nobody", -"nobs", -"nocake", -"nocent", -"nock", -"nocket", -"nocktat", -"noctuid", -"noctule", -"nocturn", -"nocuity", -"nocuous", -"nod", -"nodal", -"nodated", -"nodder", -"nodding", -"noddle", -"noddy", -"node", -"noded", -"nodi", -"nodiak", -"nodical", -"nodose", -"nodous", -"nodular", -"nodule", -"noduled", -"nodulus", -"nodus", -"noel", -"noetic", -"noetics", -"nog", -"nogada", -"nogal", -"noggen", -"noggin", -"nogging", -"noghead", -"nohow", -"noil", -"noilage", -"noiler", -"noily", -"noint", -"noir", -"noise", -"noisily", -"noisome", -"noisy", -"nokta", -"noll", -"nolle", -"nolo", -"noma", -"nomad", -"nomadic", -"nomancy", -"nomarch", -"nombril", -"nome", -"nomial", -"nomic", -"nomina", -"nominal", -"nominee", -"nominy", -"nomism", -"nomisma", -"nomos", -"non", -"nonacid", -"nonact", -"nonage", -"nonagon", -"nonaid", -"nonair", -"nonane", -"nonary", -"nonbase", -"nonce", -"noncock", -"noncom", -"noncome", -"noncon", -"nonda", -"nondo", -"none", -"nonego", -"nonene", -"nonent", -"nonepic", -"nones", -"nonet", -"nonevil", -"nonfact", -"nonfarm", -"nonfat", -"nonfood", -"nonform", -"nonfrat", -"nongas", -"nongod", -"nongold", -"nongray", -"nongrey", -"nonhero", -"nonic", -"nonion", -"nonius", -"nonjury", -"nonlife", -"nonly", -"nonnant", -"nonnat", -"nonoic", -"nonoily", -"nonomad", -"nonpaid", -"nonpar", -"nonpeak", -"nonplus", -"nonpoet", -"nonport", -"nonrun", -"nonsale", -"nonsane", -"nonself", -"nonsine", -"nonskid", -"nonslip", -"nonstop", -"nonsuit", -"nontan", -"nontax", -"nonterm", -"nonuple", -"nonuse", -"nonuser", -"nonwar", -"nonya", -"nonyl", -"nonylic", -"nonzero", -"noodle", -"nook", -"nooked", -"nookery", -"nooking", -"nooklet", -"nooky", -"noology", -"noon", -"noonday", -"nooning", -"noonlit", -"noop", -"noose", -"nooser", -"nopal", -"nopalry", -"nope", -"nor", -"norard", -"norate", -"noreast", -"norelin", -"norgine", -"nori", -"noria", -"norie", -"norimon", -"norite", -"norland", -"norm", -"norma", -"normal", -"norsel", -"north", -"norther", -"norward", -"norwest", -"nose", -"nosean", -"nosed", -"nosegay", -"noser", -"nosey", -"nosine", -"nosing", -"nosism", -"nostic", -"nostril", -"nostrum", -"nosy", -"not", -"notable", -"notably", -"notaeal", -"notaeum", -"notal", -"notan", -"notary", -"notate", -"notator", -"notch", -"notched", -"notchel", -"notcher", -"notchy", -"note", -"noted", -"notedly", -"notekin", -"notelet", -"noter", -"nother", -"nothing", -"nothous", -"notice", -"noticer", -"notify", -"notion", -"notitia", -"notour", -"notself", -"notum", -"nougat", -"nought", -"noun", -"nounal", -"nounize", -"noup", -"nourice", -"nourish", -"nous", -"nouther", -"nova", -"novalia", -"novate", -"novator", -"novcic", -"novel", -"novelet", -"novella", -"novelly", -"novelry", -"novelty", -"novem", -"novena", -"novene", -"novice", -"novity", -"now", -"nowaday", -"noway", -"noways", -"nowed", -"nowel", -"nowhat", -"nowhen", -"nowhere", -"nowhit", -"nowise", -"nowness", -"nowt", -"nowy", -"noxa", -"noxal", -"noxally", -"noxious", -"noy", -"noyade", -"noyau", -"nozzle", -"nozzler", -"nth", -"nu", -"nuance", -"nub", -"nubbin", -"nubble", -"nubbly", -"nubby", -"nubia", -"nubile", -"nucal", -"nucha", -"nuchal", -"nucin", -"nucleal", -"nuclear", -"nuclei", -"nuclein", -"nucleon", -"nucleus", -"nuclide", -"nucule", -"nuculid", -"nudate", -"nuddle", -"nude", -"nudely", -"nudge", -"nudger", -"nudiped", -"nudish", -"nudism", -"nudist", -"nudity", -"nugator", -"nuggar", -"nugget", -"nuggety", -"nugify", -"nuke", -"nul", -"null", -"nullah", -"nullify", -"nullism", -"nullity", -"nullo", -"numb", -"number", -"numbing", -"numble", -"numbles", -"numbly", -"numda", -"numdah", -"numen", -"numeral", -"numero", -"nummary", -"nummi", -"nummus", -"numud", -"nun", -"nunatak", -"nunbird", -"nunch", -"nuncio", -"nuncle", -"nundine", -"nunhood", -"nunky", -"nunlet", -"nunlike", -"nunnari", -"nunnery", -"nunni", -"nunnify", -"nunnish", -"nunship", -"nuptial", -"nuque", -"nuraghe", -"nurhag", -"nurly", -"nurse", -"nurser", -"nursery", -"nursing", -"nursle", -"nursy", -"nurture", -"nusfiah", -"nut", -"nutant", -"nutate", -"nutcake", -"nutgall", -"nuthook", -"nutlet", -"nutlike", -"nutmeg", -"nutpick", -"nutria", -"nutrice", -"nutrify", -"nutseed", -"nutted", -"nutter", -"nuttery", -"nuttily", -"nutting", -"nuttish", -"nutty", -"nuzzer", -"nuzzle", -"nyanza", -"nye", -"nylast", -"nylon", -"nymil", -"nymph", -"nympha", -"nymphae", -"nymphal", -"nymphet", -"nymphic", -"nymphid", -"nymphly", -"nyxis", -"o", -"oadal", -"oaf", -"oafdom", -"oafish", -"oak", -"oaken", -"oaklet", -"oaklike", -"oakling", -"oakum", -"oakweb", -"oakwood", -"oaky", -"oam", -"oar", -"oarage", -"oarcock", -"oared", -"oarfish", -"oarhole", -"oarial", -"oaric", -"oaritic", -"oaritis", -"oarium", -"oarless", -"oarlike", -"oarlock", -"oarlop", -"oarman", -"oarsman", -"oarweed", -"oary", -"oasal", -"oasean", -"oases", -"oasis", -"oasitic", -"oast", -"oat", -"oatbin", -"oatcake", -"oatear", -"oaten", -"oatfowl", -"oath", -"oathay", -"oathed", -"oathful", -"oathlet", -"oatland", -"oatlike", -"oatmeal", -"oatseed", -"oaty", -"oban", -"obclude", -"obe", -"obeah", -"obeche", -"obeism", -"obelia", -"obeliac", -"obelial", -"obelion", -"obelisk", -"obelism", -"obelize", -"obelus", -"obese", -"obesely", -"obesity", -"obex", -"obey", -"obeyer", -"obi", -"obispo", -"obit", -"obitual", -"object", -"objure", -"oblate", -"obley", -"oblige", -"obliged", -"obligee", -"obliger", -"obligor", -"oblique", -"oblong", -"obloquy", -"oboe", -"oboist", -"obol", -"obolary", -"obole", -"obolet", -"obolus", -"oboval", -"obovate", -"obovoid", -"obscene", -"obscure", -"obsede", -"obsequy", -"observe", -"obsess", -"obtain", -"obtect", -"obtest", -"obtrude", -"obtund", -"obtuse", -"obverse", -"obvert", -"obviate", -"obvious", -"obvolve", -"ocarina", -"occamy", -"occiput", -"occlude", -"occluse", -"occult", -"occupy", -"occur", -"ocean", -"oceaned", -"oceanet", -"oceanic", -"ocellar", -"ocelli", -"ocellus", -"oceloid", -"ocelot", -"och", -"ochava", -"ochavo", -"ocher", -"ochery", -"ochone", -"ochrea", -"ochro", -"ochroid", -"ochrous", -"ocht", -"ock", -"oclock", -"ocote", -"ocque", -"ocracy", -"ocrea", -"ocreate", -"octad", -"octadic", -"octagon", -"octan", -"octane", -"octant", -"octapla", -"octarch", -"octary", -"octaval", -"octave", -"octavic", -"octavo", -"octene", -"octet", -"octic", -"octine", -"octoad", -"octoate", -"octofid", -"octoic", -"octoid", -"octonal", -"octoon", -"octoped", -"octopi", -"octopod", -"octopus", -"octose", -"octoyl", -"octroi", -"octroy", -"octuor", -"octuple", -"octuply", -"octyl", -"octyne", -"ocuby", -"ocular", -"oculary", -"oculate", -"oculist", -"oculus", -"od", -"oda", -"odacoid", -"odal", -"odalisk", -"odaller", -"odalman", -"odd", -"oddish", -"oddity", -"oddlegs", -"oddly", -"oddman", -"oddment", -"oddness", -"odds", -"oddsman", -"ode", -"odel", -"odelet", -"odeon", -"odeum", -"odic", -"odinite", -"odious", -"odist", -"odium", -"odology", -"odontic", -"odoom", -"odor", -"odorant", -"odorate", -"odored", -"odorful", -"odorize", -"odorous", -"odso", -"odum", -"odyl", -"odylic", -"odylism", -"odylist", -"odylize", -"oe", -"oecist", -"oecus", -"oenin", -"oenolin", -"oenomel", -"oer", -"oersted", -"oes", -"oestrid", -"oestrin", -"oestrum", -"oestrus", -"of", -"off", -"offal", -"offbeat", -"offcast", -"offcome", -"offcut", -"offend", -"offense", -"offer", -"offeree", -"offerer", -"offeror", -"offhand", -"office", -"officer", -"offing", -"offish", -"offlet", -"offlook", -"offscum", -"offset", -"offtake", -"offtype", -"offward", -"oflete", -"oft", -"often", -"oftens", -"ofter", -"oftest", -"oftly", -"oftness", -"ofttime", -"ogaire", -"ogam", -"ogamic", -"ogdoad", -"ogdoas", -"ogee", -"ogeed", -"ogham", -"oghamic", -"ogival", -"ogive", -"ogived", -"ogle", -"ogler", -"ogmic", -"ogre", -"ogreish", -"ogreism", -"ogress", -"ogrish", -"ogrism", -"ogtiern", -"ogum", -"oh", -"ohelo", -"ohia", -"ohm", -"ohmage", -"ohmic", -"oho", -"ohoy", -"oidioid", -"oii", -"oil", -"oilbird", -"oilcan", -"oilcoat", -"oilcup", -"oildom", -"oiled", -"oiler", -"oilery", -"oilfish", -"oilhole", -"oilily", -"oilless", -"oillet", -"oillike", -"oilman", -"oilseed", -"oilskin", -"oilway", -"oily", -"oilyish", -"oime", -"oinomel", -"oint", -"oisin", -"oitava", -"oka", -"okapi", -"okee", -"okenite", -"oket", -"oki", -"okia", -"okonite", -"okra", -"okrug", -"olam", -"olamic", -"old", -"olden", -"older", -"oldish", -"oldland", -"oldness", -"oldster", -"oldwife", -"oleana", -"olease", -"oleate", -"olefin", -"olefine", -"oleic", -"olein", -"olena", -"olenid", -"olent", -"oleo", -"oleose", -"oleous", -"olfact", -"olfacty", -"oliban", -"olid", -"oligist", -"olio", -"olitory", -"oliva", -"olivary", -"olive", -"olived", -"olivet", -"olivil", -"olivile", -"olivine", -"olla", -"ollamh", -"ollapod", -"ollock", -"olm", -"ologist", -"ology", -"olomao", -"olona", -"oloroso", -"olpe", -"oltonde", -"oltunna", -"olycook", -"olykoek", -"om", -"omagra", -"omalgia", -"omao", -"omasum", -"omber", -"omega", -"omegoid", -"omelet", -"omen", -"omened", -"omental", -"omentum", -"omer", -"omicron", -"omina", -"ominous", -"omit", -"omitis", -"omitter", -"omlah", -"omneity", -"omniana", -"omnibus", -"omnific", -"omnify", -"omnist", -"omnium", -"on", -"ona", -"onager", -"onagra", -"onanism", -"onanist", -"onca", -"once", -"oncetta", -"oncia", -"oncin", -"oncome", -"oncosis", -"oncost", -"ondatra", -"ondine", -"ondy", -"one", -"onefold", -"onegite", -"onehow", -"oneiric", -"oneism", -"onement", -"oneness", -"oner", -"onerary", -"onerous", -"onery", -"oneself", -"onetime", -"oneyer", -"onfall", -"onflow", -"ongaro", -"ongoing", -"onicolo", -"onion", -"onionet", -"oniony", -"onium", -"onkos", -"onlay", -"onlepy", -"onliest", -"onlook", -"only", -"onmarch", -"onrush", -"ons", -"onset", -"onshore", -"onside", -"onsight", -"onstand", -"onstead", -"onsweep", -"ontal", -"onto", -"onus", -"onward", -"onwards", -"onycha", -"onychia", -"onychin", -"onym", -"onymal", -"onymity", -"onymize", -"onymous", -"onymy", -"onyx", -"onyxis", -"onza", -"ooblast", -"oocyst", -"oocyte", -"oodles", -"ooecial", -"ooecium", -"oofbird", -"ooftish", -"oofy", -"oogamy", -"oogeny", -"ooglea", -"oogone", -"oograph", -"ooid", -"ooidal", -"oolak", -"oolemma", -"oolite", -"oolitic", -"oolly", -"oologic", -"oology", -"oolong", -"oomancy", -"oometer", -"oometry", -"oons", -"oont", -"oopak", -"oophore", -"oophyte", -"ooplasm", -"ooplast", -"oopod", -"oopodal", -"oorali", -"oord", -"ooscope", -"ooscopy", -"oosperm", -"oospore", -"ootheca", -"ootid", -"ootype", -"ooze", -"oozily", -"oozooid", -"oozy", -"opacate", -"opacify", -"opacite", -"opacity", -"opacous", -"opah", -"opal", -"opaled", -"opaline", -"opalish", -"opalize", -"opaloid", -"opaque", -"ope", -"opelet", -"open", -"opener", -"opening", -"openly", -"opera", -"operae", -"operand", -"operant", -"operate", -"opercle", -"operose", -"ophic", -"ophioid", -"ophite", -"ophitic", -"ophryon", -"opianic", -"opianyl", -"opiate", -"opiatic", -"opiism", -"opinant", -"opine", -"opiner", -"opinion", -"opium", -"opossum", -"oppidan", -"oppose", -"opposed", -"opposer", -"opposit", -"oppress", -"oppugn", -"opsonic", -"opsonin", -"opsy", -"opt", -"optable", -"optably", -"optant", -"optate", -"optic", -"optical", -"opticon", -"optics", -"optimal", -"optime", -"optimum", -"option", -"optive", -"opulent", -"opulus", -"opus", -"oquassa", -"or", -"ora", -"orach", -"oracle", -"orad", -"orage", -"oral", -"oraler", -"oralism", -"oralist", -"orality", -"oralize", -"orally", -"oralogy", -"orang", -"orange", -"oranger", -"orangey", -"orant", -"orarian", -"orarion", -"orarium", -"orary", -"orate", -"oration", -"orator", -"oratory", -"oratrix", -"orb", -"orbed", -"orbic", -"orbical", -"orbicle", -"orbific", -"orbit", -"orbital", -"orbitar", -"orbite", -"orbless", -"orblet", -"orby", -"orc", -"orcanet", -"orcein", -"orchard", -"orchat", -"orchel", -"orchic", -"orchid", -"orchil", -"orcin", -"orcinol", -"ordain", -"ordeal", -"order", -"ordered", -"orderer", -"orderly", -"ordinal", -"ordinar", -"ordinee", -"ordines", -"ordu", -"ordure", -"ore", -"oread", -"orectic", -"orellin", -"oreman", -"orenda", -"oreweed", -"orewood", -"orexis", -"orf", -"orfgild", -"organ", -"organal", -"organdy", -"organer", -"organic", -"organon", -"organry", -"organum", -"orgasm", -"orgeat", -"orgia", -"orgiac", -"orgiacs", -"orgiasm", -"orgiast", -"orgic", -"orgue", -"orgy", -"orgyia", -"oribi", -"oriel", -"oriency", -"orient", -"orifice", -"oriform", -"origan", -"origin", -"orignal", -"orihon", -"orillon", -"oriole", -"orison", -"oristic", -"orle", -"orlean", -"orlet", -"orlo", -"orlop", -"ormer", -"ormolu", -"orna", -"ornate", -"ornery", -"ornis", -"ornoite", -"oroanal", -"orogen", -"orogeny", -"oroide", -"orology", -"oronoco", -"orotund", -"orphan", -"orpheon", -"orpheum", -"orphrey", -"orpine", -"orrery", -"orrhoid", -"orris", -"orsel", -"orselle", -"ort", -"ortalid", -"ortet", -"orthal", -"orthian", -"orthic", -"orthid", -"orthite", -"ortho", -"orthose", -"orthron", -"ortiga", -"ortive", -"ortolan", -"ortygan", -"ory", -"oryssid", -"os", -"osamin", -"osamine", -"osazone", -"oscella", -"oscheal", -"oscin", -"oscine", -"oscnode", -"oscular", -"oscule", -"osculum", -"ose", -"osela", -"oshac", -"oside", -"osier", -"osiered", -"osiery", -"osmate", -"osmatic", -"osmesis", -"osmetic", -"osmic", -"osmin", -"osmina", -"osmious", -"osmium", -"osmose", -"osmosis", -"osmotic", -"osmous", -"osmund", -"osone", -"osophy", -"osprey", -"ossal", -"osse", -"ossein", -"osselet", -"osseous", -"ossicle", -"ossific", -"ossify", -"ossuary", -"osteal", -"ostein", -"ostemia", -"ostent", -"osteoid", -"osteoma", -"ostial", -"ostiary", -"ostiate", -"ostiole", -"ostitis", -"ostium", -"ostmark", -"ostosis", -"ostrich", -"otalgia", -"otalgic", -"otalgy", -"otarian", -"otarine", -"otary", -"otate", -"other", -"othmany", -"otiant", -"otiatry", -"otic", -"otidine", -"otidium", -"otiose", -"otitic", -"otitis", -"otkon", -"otocyst", -"otolite", -"otolith", -"otology", -"otosis", -"ototomy", -"ottar", -"otter", -"otterer", -"otto", -"oturia", -"ouabain", -"ouabaio", -"ouabe", -"ouakari", -"ouch", -"ouenite", -"ouf", -"ough", -"ought", -"oughtnt", -"oukia", -"oulap", -"ounce", -"ounds", -"ouphe", -"ouphish", -"our", -"ourie", -"ouroub", -"ours", -"ourself", -"oust", -"ouster", -"out", -"outact", -"outage", -"outarde", -"outask", -"outawe", -"outback", -"outbake", -"outban", -"outbar", -"outbark", -"outbawl", -"outbeam", -"outbear", -"outbeg", -"outbent", -"outbid", -"outblot", -"outblow", -"outbond", -"outbook", -"outborn", -"outbow", -"outbowl", -"outbox", -"outbrag", -"outbray", -"outbred", -"outbud", -"outbulk", -"outburn", -"outbuy", -"outbuzz", -"outby", -"outcant", -"outcase", -"outcast", -"outcity", -"outcome", -"outcrop", -"outcrow", -"outcry", -"outcull", -"outcure", -"outcut", -"outdare", -"outdate", -"outdo", -"outdoer", -"outdoor", -"outdraw", -"outdure", -"outeat", -"outecho", -"outed", -"outedge", -"outen", -"outer", -"outerly", -"outeye", -"outeyed", -"outface", -"outfall", -"outfame", -"outfast", -"outfawn", -"outfeat", -"outfish", -"outfit", -"outflow", -"outflue", -"outflux", -"outfly", -"outfold", -"outfool", -"outfoot", -"outform", -"outfort", -"outgain", -"outgame", -"outgang", -"outgas", -"outgate", -"outgaze", -"outgive", -"outglad", -"outglow", -"outgnaw", -"outgo", -"outgoer", -"outgone", -"outgrin", -"outgrow", -"outgun", -"outgush", -"outhaul", -"outhear", -"outheel", -"outher", -"outhire", -"outhiss", -"outhit", -"outhold", -"outhowl", -"outhue", -"outhunt", -"outhurl", -"outhut", -"outhymn", -"outing", -"outish", -"outjazz", -"outjest", -"outjet", -"outjinx", -"outjump", -"outjut", -"outkick", -"outkill", -"outking", -"outkiss", -"outknee", -"outlaid", -"outland", -"outlash", -"outlast", -"outlaw", -"outlay", -"outlean", -"outleap", -"outler", -"outlet", -"outlie", -"outlier", -"outlimb", -"outlimn", -"outline", -"outlip", -"outlive", -"outlook", -"outlord", -"outlove", -"outlung", -"outly", -"outman", -"outmate", -"outmode", -"outmost", -"outmove", -"outname", -"outness", -"outnook", -"outoven", -"outpace", -"outpage", -"outpart", -"outpass", -"outpath", -"outpay", -"outpeal", -"outpeep", -"outpeer", -"outpick", -"outpipe", -"outpity", -"outplan", -"outplay", -"outplod", -"outplot", -"outpoll", -"outpomp", -"outpop", -"outport", -"outpost", -"outpour", -"outpray", -"outpry", -"outpull", -"outpurl", -"outpush", -"output", -"outrace", -"outrage", -"outrail", -"outrank", -"outrant", -"outrap", -"outrate", -"outrave", -"outray", -"outre", -"outread", -"outrede", -"outrick", -"outride", -"outrig", -"outring", -"outroar", -"outroll", -"outroot", -"outrove", -"outrow", -"outrun", -"outrush", -"outsail", -"outsay", -"outsea", -"outseam", -"outsee", -"outseek", -"outsell", -"outsert", -"outset", -"outshot", -"outshow", -"outshut", -"outside", -"outsift", -"outsigh", -"outsin", -"outsing", -"outsit", -"outsize", -"outskip", -"outsoar", -"outsole", -"outspan", -"outspin", -"outspit", -"outspue", -"outstay", -"outstep", -"outsuck", -"outsulk", -"outsum", -"outswim", -"outtalk", -"outtask", -"outtear", -"outtell", -"outtire", -"outtoil", -"outtop", -"outtrot", -"outturn", -"outvie", -"outvier", -"outvote", -"outwait", -"outwake", -"outwale", -"outwalk", -"outwall", -"outwar", -"outward", -"outwash", -"outwave", -"outwear", -"outweed", -"outweep", -"outwell", -"outwent", -"outwick", -"outwile", -"outwill", -"outwind", -"outwing", -"outwish", -"outwit", -"outwith", -"outwoe", -"outwood", -"outword", -"outwore", -"outwork", -"outworn", -"outyard", -"outyell", -"outyelp", -"outzany", -"ouzel", -"ova", -"oval", -"ovalish", -"ovalize", -"ovally", -"ovaloid", -"ovant", -"ovarial", -"ovarian", -"ovarin", -"ovarium", -"ovary", -"ovate", -"ovated", -"ovately", -"ovation", -"oven", -"ovenful", -"ovenly", -"ovenman", -"over", -"overact", -"overage", -"overall", -"overapt", -"overarm", -"overawe", -"overawn", -"overbet", -"overbid", -"overbig", -"overbit", -"overbow", -"overbuy", -"overby", -"overcap", -"overcow", -"overcoy", -"overcry", -"overcup", -"overcut", -"overdo", -"overdry", -"overdue", -"overdye", -"overeat", -"overegg", -"overeye", -"overfag", -"overfar", -"overfat", -"overfed", -"overfee", -"overfew", -"overfit", -"overfix", -"overfly", -"overget", -"overgo", -"overgod", -"overgun", -"overhit", -"overhot", -"overink", -"overjob", -"overjoy", -"overlap", -"overlax", -"overlay", -"overleg", -"overlie", -"overlip", -"overlow", -"overly", -"overman", -"overmix", -"overnet", -"overnew", -"overpay", -"overpet", -"overply", -"overpot", -"overrim", -"overrun", -"oversad", -"oversea", -"oversee", -"overset", -"oversew", -"oversot", -"oversow", -"overt", -"overtax", -"overtip", -"overtly", -"overtoe", -"overtop", -"overuse", -"overway", -"overweb", -"overwet", -"overwin", -"ovest", -"ovey", -"ovicell", -"ovicide", -"ovicyst", -"oviduct", -"oviform", -"ovigerm", -"ovile", -"ovine", -"ovinia", -"ovipara", -"ovisac", -"ovism", -"ovist", -"ovistic", -"ovocyte", -"ovoid", -"ovoidal", -"ovolo", -"ovology", -"ovular", -"ovulary", -"ovulate", -"ovule", -"ovulist", -"ovum", -"ow", -"owd", -"owe", -"owelty", -"ower", -"owerby", -"owght", -"owing", -"owk", -"owl", -"owldom", -"owler", -"owlery", -"owlet", -"owlhead", -"owling", -"owlish", -"owlism", -"owllike", -"owly", -"own", -"owner", -"ownhood", -"ownness", -"ownself", -"owrehip", -"owrelay", -"owse", -"owsen", -"owser", -"owtchah", -"ox", -"oxacid", -"oxalan", -"oxalate", -"oxalic", -"oxalite", -"oxalyl", -"oxamate", -"oxamic", -"oxamid", -"oxamide", -"oxan", -"oxanate", -"oxane", -"oxanic", -"oxazine", -"oxazole", -"oxbane", -"oxberry", -"oxbird", -"oxbiter", -"oxblood", -"oxbow", -"oxboy", -"oxbrake", -"oxcart", -"oxcheek", -"oxea", -"oxeate", -"oxen", -"oxeote", -"oxer", -"oxetone", -"oxeye", -"oxfly", -"oxgang", -"oxgoad", -"oxhead", -"oxheal", -"oxheart", -"oxhide", -"oxhoft", -"oxhorn", -"oxhouse", -"oxhuvud", -"oxidant", -"oxidase", -"oxidate", -"oxide", -"oxidic", -"oxidize", -"oximate", -"oxime", -"oxland", -"oxlike", -"oxlip", -"oxman", -"oxonic", -"oxonium", -"oxozone", -"oxphony", -"oxreim", -"oxshoe", -"oxskin", -"oxtail", -"oxter", -"oxwort", -"oxy", -"oxyacid", -"oxygas", -"oxygen", -"oxyl", -"oxymel", -"oxyntic", -"oxyopia", -"oxysalt", -"oxytone", -"oyapock", -"oyer", -"oyster", -"ozena", -"ozonate", -"ozone", -"ozoned", -"ozonic", -"ozonide", -"ozonify", -"ozonize", -"ozonous", -"ozophen", -"ozotype", -"p", -"pa", -"paal", -"paar", -"paauw", -"pabble", -"pablo", -"pabouch", -"pabular", -"pabulum", -"pac", -"paca", -"pacable", -"pacate", -"pacay", -"pacaya", -"pace", -"paced", -"pacer", -"pachak", -"pachisi", -"pacific", -"pacify", -"pack", -"package", -"packer", -"packery", -"packet", -"packly", -"packman", -"packway", -"paco", -"pact", -"paction", -"pad", -"padder", -"padding", -"paddle", -"paddled", -"paddler", -"paddock", -"paddy", -"padella", -"padfoot", -"padge", -"padle", -"padlike", -"padlock", -"padnag", -"padre", -"padtree", -"paean", -"paegel", -"paegle", -"paenula", -"paeon", -"paeonic", -"paga", -"pagan", -"paganic", -"paganly", -"paganry", -"page", -"pageant", -"pagedom", -"pageful", -"pager", -"pagina", -"paginal", -"pagoda", -"pagrus", -"pagurid", -"pagus", -"pah", -"paha", -"pahi", -"pahlavi", -"pahmi", -"paho", -"pahutan", -"paigle", -"paik", -"pail", -"pailful", -"pailou", -"pain", -"pained", -"painful", -"paining", -"paint", -"painted", -"painter", -"painty", -"paip", -"pair", -"paired", -"pairer", -"pais", -"paisa", -"paiwari", -"pajama", -"pajock", -"pakchoi", -"pakeha", -"paktong", -"pal", -"palace", -"palaced", -"paladin", -"palaite", -"palama", -"palame", -"palanka", -"palar", -"palas", -"palatal", -"palate", -"palated", -"palatic", -"palaver", -"palay", -"palazzi", -"palch", -"pale", -"palea", -"paleate", -"paled", -"palely", -"paleola", -"paler", -"palet", -"paletot", -"palette", -"paletz", -"palfrey", -"palgat", -"pali", -"palikar", -"palila", -"palinal", -"paling", -"palisfy", -"palish", -"palkee", -"pall", -"palla", -"pallae", -"pallah", -"pallall", -"palled", -"pallet", -"palli", -"pallial", -"pallid", -"pallion", -"pallium", -"pallone", -"pallor", -"pally", -"palm", -"palma", -"palmad", -"palmar", -"palmary", -"palmate", -"palmed", -"palmer", -"palmery", -"palmful", -"palmist", -"palmite", -"palmito", -"palmo", -"palmula", -"palmus", -"palmy", -"palmyra", -"palolo", -"palp", -"palpal", -"palpate", -"palped", -"palpi", -"palpon", -"palpus", -"palsied", -"palster", -"palsy", -"palt", -"palter", -"paltry", -"paludal", -"paludic", -"palule", -"palulus", -"palus", -"paly", -"pam", -"pament", -"pamment", -"pampas", -"pampean", -"pamper", -"pampero", -"pampre", -"pan", -"panace", -"panacea", -"panache", -"panada", -"panade", -"panama", -"panaris", -"panary", -"panax", -"pancake", -"pand", -"panda", -"pandal", -"pandan", -"pandect", -"pandemy", -"pander", -"pandita", -"pandle", -"pandora", -"pandour", -"pandrop", -"pandura", -"pandy", -"pane", -"paned", -"paneity", -"panel", -"panela", -"paneler", -"panfil", -"panfish", -"panful", -"pang", -"pangamy", -"pangane", -"pangen", -"pangene", -"pangful", -"pangi", -"panhead", -"panic", -"panical", -"panicky", -"panicle", -"panisc", -"panisca", -"panisic", -"pank", -"pankin", -"panman", -"panmixy", -"panmug", -"pannade", -"pannage", -"pannam", -"panne", -"pannel", -"panner", -"pannery", -"pannier", -"panning", -"pannose", -"pannum", -"pannus", -"panocha", -"panoche", -"panoply", -"panoram", -"panse", -"panside", -"pansied", -"pansy", -"pant", -"pantas", -"panter", -"panther", -"pantie", -"panties", -"pantile", -"panting", -"pantle", -"pantler", -"panto", -"pantod", -"panton", -"pantoon", -"pantoum", -"pantry", -"pants", -"pantun", -"panty", -"panung", -"panurgy", -"panyar", -"paolo", -"paon", -"pap", -"papa", -"papable", -"papabot", -"papacy", -"papain", -"papal", -"papally", -"papalty", -"papane", -"papaw", -"papaya", -"papboat", -"pape", -"paper", -"papered", -"paperer", -"papern", -"papery", -"papess", -"papey", -"papilla", -"papion", -"papish", -"papism", -"papist", -"papize", -"papless", -"papmeat", -"papoose", -"pappi", -"pappose", -"pappox", -"pappus", -"pappy", -"papreg", -"paprica", -"paprika", -"papula", -"papular", -"papule", -"papyr", -"papyral", -"papyri", -"papyrin", -"papyrus", -"paquet", -"par", -"para", -"parable", -"paracme", -"parade", -"parader", -"parado", -"parados", -"paradox", -"parafle", -"parage", -"paragon", -"parah", -"paraiba", -"parale", -"param", -"paramo", -"parang", -"parao", -"parapet", -"paraph", -"parapod", -"pararek", -"parasol", -"paraspy", -"parate", -"paraxon", -"parbake", -"parboil", -"parcel", -"parch", -"parcher", -"parchy", -"parcook", -"pard", -"pardao", -"parded", -"pardesi", -"pardine", -"pardner", -"pardo", -"pardon", -"pare", -"parel", -"parella", -"paren", -"parent", -"parer", -"paresis", -"paretic", -"parfait", -"pargana", -"parge", -"parget", -"pargo", -"pari", -"pariah", -"parial", -"parian", -"paries", -"parify", -"parilla", -"parine", -"paring", -"parish", -"parisis", -"parison", -"parity", -"park", -"parka", -"parkee", -"parker", -"parkin", -"parking", -"parkish", -"parkway", -"parky", -"parlay", -"parle", -"parley", -"parling", -"parlish", -"parlor", -"parlous", -"parly", -"parma", -"parmak", -"parnas", -"parnel", -"paroch", -"parode", -"parodic", -"parodos", -"parody", -"paroecy", -"parol", -"parole", -"parolee", -"paroli", -"paronym", -"parotic", -"parotid", -"parotis", -"parous", -"parpal", -"parquet", -"parr", -"parrel", -"parrier", -"parrock", -"parrot", -"parroty", -"parry", -"parse", -"parsec", -"parser", -"parsley", -"parsnip", -"parson", -"parsony", -"part", -"partake", -"partan", -"parted", -"parter", -"partial", -"partile", -"partite", -"partlet", -"partly", -"partner", -"parto", -"partook", -"parture", -"party", -"parulis", -"parure", -"paruria", -"parvenu", -"parvis", -"parvule", -"pasan", -"pasang", -"paschal", -"pascual", -"pash", -"pasha", -"pashm", -"pasi", -"pasmo", -"pasquil", -"pasquin", -"pass", -"passade", -"passado", -"passage", -"passant", -"passe", -"passee", -"passen", -"passer", -"passewa", -"passing", -"passion", -"passir", -"passive", -"passkey", -"passman", -"passo", -"passout", -"passus", -"passway", -"past", -"paste", -"pasted", -"pastel", -"paster", -"pastern", -"pasteur", -"pastil", -"pastile", -"pastime", -"pasting", -"pastor", -"pastose", -"pastry", -"pasture", -"pasty", -"pasul", -"pat", -"pata", -"pataca", -"patacao", -"pataco", -"patagon", -"pataka", -"patamar", -"patao", -"patapat", -"pataque", -"patas", -"patball", -"patch", -"patcher", -"patchy", -"pate", -"patefy", -"patel", -"patella", -"paten", -"patency", -"patener", -"patent", -"pater", -"patera", -"patesi", -"path", -"pathed", -"pathema", -"pathic", -"pathlet", -"pathos", -"pathway", -"pathy", -"patible", -"patient", -"patina", -"patine", -"patined", -"patio", -"patly", -"patness", -"pato", -"patois", -"patola", -"patonce", -"patria", -"patrial", -"patrice", -"patrico", -"patrin", -"patriot", -"patrist", -"patrix", -"patrol", -"patron", -"patroon", -"patta", -"patte", -"pattee", -"patten", -"patter", -"pattern", -"pattu", -"patty", -"patu", -"patwari", -"paty", -"pau", -"paucify", -"paucity", -"paughty", -"paukpan", -"paular", -"paulie", -"paulin", -"paunch", -"paunchy", -"paup", -"pauper", -"pausal", -"pause", -"pauser", -"paussid", -"paut", -"pauxi", -"pavage", -"pavan", -"pavane", -"pave", -"paver", -"pavid", -"pavier", -"paving", -"pavior", -"paviour", -"pavis", -"paviser", -"pavisor", -"pavy", -"paw", -"pawdite", -"pawer", -"pawing", -"pawk", -"pawkery", -"pawkily", -"pawkrie", -"pawky", -"pawl", -"pawn", -"pawnage", -"pawnee", -"pawner", -"pawnie", -"pawnor", -"pawpaw", -"pax", -"paxilla", -"paxiuba", -"paxwax", -"pay", -"payable", -"payably", -"payday", -"payed", -"payee", -"payeny", -"payer", -"paying", -"payment", -"paynim", -"payoff", -"payong", -"payor", -"payroll", -"pea", -"peace", -"peach", -"peachen", -"peacher", -"peachy", -"peacoat", -"peacock", -"peacod", -"peafowl", -"peag", -"peage", -"peahen", -"peai", -"peaiism", -"peak", -"peaked", -"peaker", -"peakily", -"peaking", -"peakish", -"peaky", -"peal", -"pealike", -"pean", -"peanut", -"pear", -"pearl", -"pearled", -"pearler", -"pearlet", -"pearlin", -"pearly", -"peart", -"pearten", -"peartly", -"peasant", -"peasen", -"peason", -"peasy", -"peat", -"peatery", -"peatman", -"peaty", -"peavey", -"peavy", -"peba", -"pebble", -"pebbled", -"pebbly", -"pebrine", -"pecan", -"peccant", -"peccary", -"peccavi", -"pech", -"pecht", -"pecite", -"peck", -"pecked", -"pecker", -"pecket", -"peckful", -"peckish", -"peckle", -"peckled", -"peckly", -"pecky", -"pectase", -"pectate", -"pecten", -"pectic", -"pectin", -"pectize", -"pectora", -"pectose", -"pectous", -"pectus", -"ped", -"peda", -"pedage", -"pedagog", -"pedal", -"pedaler", -"pedant", -"pedary", -"pedate", -"pedated", -"pedder", -"peddle", -"peddler", -"pedee", -"pedes", -"pedesis", -"pedicab", -"pedicel", -"pedicle", -"pedion", -"pedlar", -"pedlary", -"pedocal", -"pedrail", -"pedrero", -"pedro", -"pedule", -"pedum", -"pee", -"peed", -"peek", -"peel", -"peele", -"peeled", -"peeler", -"peeling", -"peelman", -"peen", -"peenge", -"peeoy", -"peep", -"peeper", -"peepeye", -"peepy", -"peer", -"peerage", -"peerdom", -"peeress", -"peerie", -"peerly", -"peery", -"peesash", -"peeve", -"peeved", -"peever", -"peevish", -"peewee", -"peg", -"pega", -"pegall", -"pegasid", -"pegbox", -"pegged", -"pegger", -"pegging", -"peggle", -"peggy", -"pegless", -"peglet", -"peglike", -"pegman", -"pegwood", -"peho", -"peine", -"peisage", -"peise", -"peiser", -"peixere", -"pekan", -"pekin", -"pekoe", -"peladic", -"pelage", -"pelagic", -"pelamyd", -"pelanos", -"pelean", -"pelecan", -"pelf", -"pelican", -"pelick", -"pelike", -"peliom", -"pelioma", -"pelisse", -"pelite", -"pelitic", -"pell", -"pellage", -"pellar", -"pellard", -"pellas", -"pellate", -"peller", -"pellet", -"pellety", -"pellile", -"pellock", -"pelmet", -"pelon", -"peloria", -"peloric", -"pelorus", -"pelota", -"peloton", -"pelt", -"pelta", -"peltast", -"peltate", -"pelter", -"pelting", -"peltry", -"pelu", -"peludo", -"pelves", -"pelvic", -"pelvis", -"pembina", -"pemican", -"pen", -"penal", -"penally", -"penalty", -"penance", -"penang", -"penates", -"penbard", -"pence", -"pencel", -"pencil", -"pend", -"penda", -"pendant", -"pendent", -"pending", -"pendle", -"pendom", -"pendule", -"penfold", -"penful", -"pengo", -"penguin", -"penhead", -"penial", -"penide", -"penile", -"penis", -"penk", -"penlike", -"penman", -"penna", -"pennae", -"pennage", -"pennant", -"pennate", -"penner", -"pennet", -"penni", -"pennia", -"pennied", -"pennill", -"penning", -"pennon", -"penny", -"penrack", -"penship", -"pensile", -"pension", -"pensive", -"penster", -"pensum", -"pensy", -"pent", -"penta", -"pentace", -"pentad", -"pentail", -"pentane", -"pentene", -"pentine", -"pentit", -"pentite", -"pentode", -"pentoic", -"pentol", -"pentose", -"pentrit", -"pentyl", -"pentyne", -"penuchi", -"penult", -"penury", -"peon", -"peonage", -"peonism", -"peony", -"people", -"peopler", -"peoplet", -"peotomy", -"pep", -"pepful", -"pepino", -"peplos", -"peplum", -"peplus", -"pepo", -"pepper", -"peppery", -"peppily", -"peppin", -"peppy", -"pepsin", -"pepsis", -"peptic", -"peptide", -"peptize", -"peptone", -"per", -"peracid", -"peract", -"perbend", -"percale", -"percent", -"percept", -"perch", -"percha", -"percher", -"percid", -"percoct", -"percoid", -"percur", -"percuss", -"perdu", -"perdure", -"pereion", -"pereira", -"peres", -"perfect", -"perfidy", -"perform", -"perfume", -"perfumy", -"perfuse", -"pergola", -"perhaps", -"peri", -"periapt", -"peridot", -"perigee", -"perigon", -"peril", -"perine", -"period", -"periost", -"perique", -"perish", -"perit", -"perite", -"periwig", -"perjink", -"perjure", -"perjury", -"perk", -"perkily", -"perkin", -"perking", -"perkish", -"perky", -"perle", -"perlid", -"perlite", -"perloir", -"perm", -"permit", -"permute", -"pern", -"pernine", -"pernor", -"pernyi", -"peroba", -"peropod", -"peropus", -"peroral", -"perosis", -"perotic", -"peroxy", -"peroxyl", -"perpend", -"perpera", -"perplex", -"perrier", -"perron", -"perry", -"persalt", -"perse", -"persico", -"persis", -"persist", -"person", -"persona", -"pert", -"pertain", -"perten", -"pertish", -"pertly", -"perturb", -"pertuse", -"perty", -"peruke", -"perula", -"perule", -"perusal", -"peruse", -"peruser", -"pervade", -"pervert", -"pes", -"pesa", -"pesade", -"pesage", -"peseta", -"peshkar", -"peshwa", -"peskily", -"pesky", -"peso", -"pess", -"pessary", -"pest", -"peste", -"pester", -"pestful", -"pestify", -"pestle", -"pet", -"petal", -"petaled", -"petalon", -"petaly", -"petard", -"petary", -"petasos", -"petasus", -"petcock", -"pete", -"peteca", -"peteman", -"peter", -"petful", -"petiole", -"petit", -"petite", -"petitor", -"petkin", -"petling", -"peto", -"petrary", -"petre", -"petrean", -"petrel", -"petrie", -"petrify", -"petrol", -"petrosa", -"petrous", -"petted", -"petter", -"pettily", -"pettish", -"pettle", -"petty", -"petune", -"petwood", -"petzite", -"peuhl", -"pew", -"pewage", -"pewdom", -"pewee", -"pewful", -"pewing", -"pewit", -"pewless", -"pewmate", -"pewter", -"pewtery", -"pewy", -"peyote", -"peyotl", -"peyton", -"peytrel", -"pfennig", -"pfui", -"pfund", -"phacoid", -"phaeism", -"phaeton", -"phage", -"phalanx", -"phalera", -"phallic", -"phallin", -"phallus", -"phanic", -"phano", -"phantom", -"phare", -"pharmic", -"pharos", -"pharynx", -"phase", -"phaseal", -"phasemy", -"phases", -"phasic", -"phasis", -"phasm", -"phasma", -"phasmid", -"pheal", -"phellem", -"phemic", -"phenate", -"phene", -"phenene", -"phenic", -"phenin", -"phenol", -"phenyl", -"pheon", -"phew", -"phi", -"phial", -"phiale", -"philter", -"philtra", -"phit", -"phiz", -"phizes", -"phizog", -"phlegm", -"phlegma", -"phlegmy", -"phloem", -"phloxin", -"pho", -"phobiac", -"phobic", -"phobism", -"phobist", -"phoby", -"phoca", -"phocal", -"phocid", -"phocine", -"phocoid", -"phoebe", -"phoenix", -"phoh", -"pholad", -"pholcid", -"pholido", -"phon", -"phonal", -"phonate", -"phone", -"phoneme", -"phonic", -"phonics", -"phonism", -"phono", -"phony", -"phoo", -"phoresy", -"phoria", -"phorid", -"phorone", -"phos", -"phose", -"phosis", -"phospho", -"phossy", -"phot", -"photal", -"photic", -"photics", -"photism", -"photo", -"photoma", -"photon", -"phragma", -"phrasal", -"phrase", -"phraser", -"phrasy", -"phrator", -"phratry", -"phrenic", -"phrynid", -"phrynin", -"phthor", -"phu", -"phugoid", -"phulwa", -"phut", -"phycite", -"phyla", -"phyle", -"phylic", -"phyllin", -"phylon", -"phylum", -"phyma", -"phymata", -"physic", -"physics", -"phytase", -"phytic", -"phytin", -"phytoid", -"phytol", -"phytoma", -"phytome", -"phyton", -"phytyl", -"pi", -"pia", -"piaba", -"piacaba", -"piacle", -"piaffe", -"piaffer", -"pial", -"pialyn", -"pian", -"pianic", -"pianino", -"pianism", -"pianist", -"piannet", -"piano", -"pianola", -"piaster", -"piastre", -"piation", -"piazine", -"piazza", -"pibcorn", -"pibroch", -"pic", -"pica", -"picador", -"pical", -"picamar", -"picara", -"picarel", -"picaro", -"picary", -"piccolo", -"pice", -"picene", -"piceous", -"pichi", -"picine", -"pick", -"pickage", -"pickax", -"picked", -"pickee", -"pickeer", -"picker", -"pickery", -"picket", -"pickle", -"pickler", -"pickman", -"pickmaw", -"pickup", -"picky", -"picnic", -"pico", -"picoid", -"picot", -"picotah", -"picotee", -"picra", -"picrate", -"picric", -"picrite", -"picrol", -"picryl", -"pict", -"picture", -"pictury", -"picuda", -"picudo", -"picul", -"piculet", -"pidan", -"piddle", -"piddler", -"piddock", -"pidgin", -"pie", -"piebald", -"piece", -"piecen", -"piecer", -"piecing", -"pied", -"piedly", -"pieless", -"pielet", -"pielum", -"piemag", -"pieman", -"pien", -"piend", -"piepan", -"pier", -"pierage", -"pierce", -"pierced", -"piercel", -"piercer", -"pierid", -"pierine", -"pierrot", -"pieshop", -"piet", -"pietas", -"pietic", -"pietism", -"pietist", -"pietose", -"piety", -"piewife", -"piewipe", -"piezo", -"piff", -"piffle", -"piffler", -"pifine", -"pig", -"pigdan", -"pigdom", -"pigeon", -"pigface", -"pigfish", -"pigfoot", -"pigful", -"piggery", -"piggin", -"pigging", -"piggish", -"piggle", -"piggy", -"pighead", -"pigherd", -"pightle", -"pigless", -"piglet", -"pigling", -"pigly", -"pigman", -"pigment", -"pignon", -"pignus", -"pignut", -"pigpen", -"pigroot", -"pigskin", -"pigsney", -"pigsty", -"pigtail", -"pigwash", -"pigweed", -"pigyard", -"piitis", -"pik", -"pika", -"pike", -"piked", -"pikel", -"pikelet", -"pikeman", -"piker", -"pikey", -"piki", -"piking", -"pikle", -"piky", -"pilage", -"pilapil", -"pilar", -"pilary", -"pilau", -"pilaued", -"pilch", -"pilcher", -"pilcorn", -"pilcrow", -"pile", -"pileata", -"pileate", -"piled", -"pileous", -"piler", -"piles", -"pileus", -"pilfer", -"pilger", -"pilgrim", -"pili", -"pilifer", -"piligan", -"pilikai", -"pilin", -"piline", -"piling", -"pilkins", -"pill", -"pillage", -"pillar", -"pillary", -"pillas", -"pillbox", -"pilled", -"pillet", -"pilleus", -"pillion", -"pillory", -"pillow", -"pillowy", -"pilm", -"pilmy", -"pilon", -"pilori", -"pilose", -"pilosis", -"pilot", -"pilotee", -"pilotry", -"pilous", -"pilpul", -"piltock", -"pilula", -"pilular", -"pilule", -"pilum", -"pilus", -"pily", -"pimaric", -"pimelic", -"pimento", -"pimlico", -"pimola", -"pimp", -"pimpery", -"pimping", -"pimpish", -"pimple", -"pimpled", -"pimplo", -"pimploe", -"pimply", -"pin", -"pina", -"pinaces", -"pinacle", -"pinacol", -"pinang", -"pinax", -"pinball", -"pinbone", -"pinbush", -"pincase", -"pincer", -"pincers", -"pinch", -"pinche", -"pinched", -"pinchem", -"pincher", -"pind", -"pinda", -"pinder", -"pindy", -"pine", -"pineal", -"pined", -"pinene", -"piner", -"pinery", -"pinesap", -"pinetum", -"piney", -"pinfall", -"pinfish", -"pinfold", -"ping", -"pingle", -"pingler", -"pingue", -"pinguid", -"pinguin", -"pinhead", -"pinhold", -"pinhole", -"pinhook", -"pinic", -"pining", -"pinion", -"pinite", -"pinitol", -"pinjane", -"pinjra", -"pink", -"pinked", -"pinkeen", -"pinken", -"pinker", -"pinkeye", -"pinkie", -"pinkify", -"pinkily", -"pinking", -"pinkish", -"pinkly", -"pinky", -"pinless", -"pinlock", -"pinna", -"pinnace", -"pinnae", -"pinnal", -"pinnate", -"pinned", -"pinnel", -"pinner", -"pinnet", -"pinning", -"pinnock", -"pinnula", -"pinnule", -"pinny", -"pino", -"pinole", -"pinolia", -"pinolin", -"pinon", -"pinonic", -"pinrail", -"pinsons", -"pint", -"pinta", -"pintado", -"pintail", -"pintano", -"pinte", -"pintle", -"pinto", -"pintura", -"pinulus", -"pinweed", -"pinwing", -"pinwork", -"pinworm", -"piny", -"pinyl", -"pinyon", -"pioneer", -"pioted", -"piotine", -"piotty", -"pioury", -"pious", -"piously", -"pip", -"pipa", -"pipage", -"pipal", -"pipe", -"pipeage", -"piped", -"pipeful", -"pipeman", -"piper", -"piperic", -"piperly", -"piperno", -"pipery", -"pipet", -"pipette", -"pipi", -"piping", -"pipiri", -"pipit", -"pipkin", -"pipless", -"pipped", -"pipper", -"pippin", -"pippy", -"piprine", -"piproid", -"pipy", -"piquant", -"pique", -"piquet", -"piquia", -"piqure", -"pir", -"piracy", -"piragua", -"piranha", -"pirate", -"piraty", -"pirl", -"pirn", -"pirner", -"pirnie", -"pirny", -"pirogue", -"pirol", -"pirr", -"pirrmaw", -"pisaca", -"pisang", -"pisay", -"piscary", -"piscian", -"piscina", -"piscine", -"pisco", -"pise", -"pish", -"pishaug", -"pishu", -"pisk", -"pisky", -"pismire", -"piso", -"piss", -"pissant", -"pist", -"pistic", -"pistil", -"pistle", -"pistol", -"pistole", -"piston", -"pistrix", -"pit", -"pita", -"pitanga", -"pitapat", -"pitarah", -"pitau", -"pitaya", -"pitch", -"pitcher", -"pitchi", -"pitchy", -"piteous", -"pitfall", -"pith", -"pithful", -"pithily", -"pithole", -"pithos", -"pithy", -"pitier", -"pitiful", -"pitless", -"pitlike", -"pitman", -"pitmark", -"pitmirk", -"pitpan", -"pitpit", -"pitside", -"pitted", -"pitter", -"pittine", -"pitting", -"pittite", -"pittoid", -"pituite", -"pituri", -"pitwood", -"pitwork", -"pity", -"pitying", -"piuri", -"pivalic", -"pivot", -"pivotal", -"pivoter", -"pix", -"pixie", -"pixy", -"pize", -"pizza", -"pizzle", -"placard", -"placate", -"place", -"placebo", -"placer", -"placet", -"placid", -"plack", -"placket", -"placode", -"placoid", -"placula", -"plaga", -"plagal", -"plagate", -"plage", -"plagium", -"plagose", -"plague", -"plagued", -"plaguer", -"plaguy", -"plaice", -"plaid", -"plaided", -"plaidie", -"plaidy", -"plain", -"plainer", -"plainly", -"plaint", -"plait", -"plaited", -"plaiter", -"plak", -"plakat", -"plan", -"planaea", -"planar", -"planate", -"planch", -"plandok", -"plane", -"planer", -"planet", -"planeta", -"planful", -"plang", -"plangor", -"planish", -"planity", -"plank", -"planker", -"planky", -"planner", -"plant", -"planta", -"plantad", -"plantal", -"plantar", -"planter", -"planula", -"planury", -"planxty", -"plap", -"plaque", -"plash", -"plasher", -"plashet", -"plashy", -"plasm", -"plasma", -"plasmic", -"plasome", -"plass", -"plasson", -"plaster", -"plastic", -"plastid", -"plastin", -"plat", -"platan", -"platane", -"platano", -"platch", -"plate", -"platea", -"plateau", -"plated", -"platen", -"plater", -"platery", -"platic", -"platina", -"plating", -"platode", -"platoid", -"platoon", -"platted", -"platten", -"platter", -"platty", -"platy", -"plaud", -"plaudit", -"play", -"playa", -"playbox", -"playboy", -"playday", -"player", -"playful", -"playlet", -"playman", -"playock", -"playpen", -"plaza", -"plea", -"pleach", -"plead", -"pleader", -"please", -"pleaser", -"pleat", -"pleater", -"pleb", -"plebe", -"plebify", -"plebs", -"pleck", -"plectre", -"pled", -"pledge", -"pledgee", -"pledger", -"pledget", -"pledgor", -"pleion", -"plenary", -"plenipo", -"plenish", -"plenism", -"plenist", -"plenty", -"plenum", -"pleny", -"pleon", -"pleonal", -"pleonic", -"pleopod", -"pleroma", -"plerome", -"plessor", -"pleura", -"pleural", -"pleuric", -"pleuron", -"pleurum", -"plew", -"plex", -"plexal", -"plexor", -"plexure", -"plexus", -"pliable", -"pliably", -"pliancy", -"pliant", -"plica", -"plical", -"plicate", -"plied", -"plier", -"plies", -"pliers", -"plight", -"plim", -"plinth", -"pliskie", -"plisky", -"ploat", -"ploce", -"plock", -"plod", -"plodder", -"plodge", -"plomb", -"plook", -"plop", -"plosion", -"plosive", -"plot", -"plote", -"plotful", -"plotted", -"plotter", -"plotty", -"plough", -"plouk", -"plouked", -"plouky", -"plounce", -"plout", -"plouter", -"plover", -"plovery", -"plow", -"plowboy", -"plower", -"plowing", -"plowman", -"ploy", -"pluck", -"plucked", -"plucker", -"plucky", -"plud", -"pluff", -"pluffer", -"pluffy", -"plug", -"plugged", -"plugger", -"pluggy", -"plugman", -"plum", -"pluma", -"plumach", -"plumade", -"plumage", -"plumate", -"plumb", -"plumber", -"plumbet", -"plumbic", -"plumbog", -"plumbum", -"plumcot", -"plume", -"plumed", -"plumer", -"plumery", -"plumet", -"plumier", -"plumify", -"plumist", -"plumlet", -"plummer", -"plummet", -"plummy", -"plumose", -"plumous", -"plump", -"plumpen", -"plumper", -"plumply", -"plumps", -"plumpy", -"plumula", -"plumule", -"plumy", -"plunder", -"plunge", -"plunger", -"plunk", -"plup", -"plural", -"pluries", -"plurify", -"plus", -"plush", -"plushed", -"plushy", -"pluteal", -"plutean", -"pluteus", -"pluvial", -"pluvian", -"pluvine", -"ply", -"plyer", -"plying", -"plywood", -"pneuma", -"po", -"poach", -"poacher", -"poachy", -"poalike", -"pob", -"pobby", -"pobs", -"pochade", -"pochard", -"pochay", -"poche", -"pock", -"pocket", -"pockety", -"pockily", -"pocky", -"poco", -"pocosin", -"pod", -"podagra", -"podal", -"podalic", -"podatus", -"podded", -"podder", -"poddish", -"poddle", -"poddy", -"podeon", -"podesta", -"podex", -"podge", -"podger", -"podgily", -"podgy", -"podial", -"podical", -"podices", -"podite", -"poditic", -"poditti", -"podium", -"podler", -"podley", -"podlike", -"podogyn", -"podsol", -"poduran", -"podurid", -"podware", -"podzol", -"poe", -"poem", -"poemet", -"poemlet", -"poesie", -"poesis", -"poesy", -"poet", -"poetdom", -"poetess", -"poetic", -"poetics", -"poetito", -"poetize", -"poetly", -"poetry", -"pogge", -"poggy", -"pogonip", -"pogrom", -"pogy", -"poh", -"poha", -"pohna", -"poi", -"poietic", -"poignet", -"poil", -"poilu", -"poind", -"poinder", -"point", -"pointed", -"pointel", -"pointer", -"pointy", -"poise", -"poised", -"poiser", -"poison", -"poitrel", -"pokable", -"poke", -"poked", -"pokeful", -"pokeout", -"poker", -"pokey", -"pokily", -"poking", -"pokomoo", -"pokunt", -"poky", -"pol", -"polacca", -"polack", -"polacre", -"polar", -"polaric", -"polarly", -"polaxis", -"poldavy", -"polder", -"pole", -"polearm", -"poleax", -"poleaxe", -"polecat", -"poleman", -"polemic", -"polenta", -"poler", -"poley", -"poliad", -"police", -"policed", -"policy", -"poligar", -"polio", -"polis", -"polish", -"polite", -"politic", -"polity", -"polk", -"polka", -"poll", -"pollack", -"polladz", -"pollage", -"pollam", -"pollan", -"pollard", -"polled", -"pollen", -"pollent", -"poller", -"pollex", -"polling", -"pollock", -"polloi", -"pollute", -"pollux", -"polo", -"poloist", -"polony", -"polos", -"polska", -"polt", -"poltina", -"poly", -"polyact", -"polyad", -"polygam", -"polygon", -"polygyn", -"polymer", -"polyose", -"polyp", -"polyped", -"polypi", -"polypod", -"polypus", -"pom", -"pomace", -"pomade", -"pomane", -"pomate", -"pomato", -"pomatum", -"pombe", -"pombo", -"pome", -"pomelo", -"pomey", -"pomfret", -"pomme", -"pommee", -"pommel", -"pommet", -"pommey", -"pommy", -"pomonal", -"pomonic", -"pomp", -"pompa", -"pompal", -"pompano", -"pompey", -"pomphus", -"pompier", -"pompion", -"pompist", -"pompon", -"pompous", -"pomster", -"pon", -"ponce", -"ponceau", -"poncho", -"pond", -"pondage", -"ponder", -"pondful", -"pondlet", -"pondman", -"pondok", -"pondus", -"pondy", -"pone", -"ponent", -"ponerid", -"poney", -"pong", -"ponga", -"pongee", -"poniard", -"ponica", -"ponier", -"ponja", -"pont", -"pontage", -"pontal", -"pontee", -"pontes", -"pontic", -"pontiff", -"pontify", -"pontil", -"pontile", -"pontin", -"pontine", -"pontist", -"ponto", -"ponton", -"pontoon", -"pony", -"ponzite", -"pooa", -"pooch", -"pooder", -"poodle", -"poof", -"poogye", -"pooh", -"pook", -"pooka", -"pookaun", -"pookoo", -"pool", -"pooler", -"pooli", -"pooly", -"poon", -"poonac", -"poonga", -"poop", -"pooped", -"poor", -"poorish", -"poorly", -"poot", -"pop", -"popadam", -"popal", -"popcorn", -"popdock", -"pope", -"popedom", -"popeism", -"popeler", -"popely", -"popery", -"popess", -"popeye", -"popeyed", -"popgun", -"popify", -"popinac", -"popish", -"popjoy", -"poplar", -"poplin", -"popover", -"poppa", -"poppean", -"poppel", -"popper", -"poppet", -"poppied", -"poppin", -"popple", -"popply", -"poppy", -"popshop", -"popular", -"populin", -"popweed", -"poral", -"porcate", -"porch", -"porched", -"porcine", -"pore", -"pored", -"porer", -"porge", -"porger", -"porgy", -"poring", -"porism", -"porite", -"pork", -"porker", -"porkery", -"porket", -"porkish", -"porkman", -"porkpie", -"porky", -"porogam", -"poroma", -"poros", -"porose", -"porosis", -"porotic", -"porous", -"porr", -"porrect", -"porret", -"porrigo", -"porry", -"port", -"porta", -"portage", -"portail", -"portal", -"portass", -"ported", -"portend", -"portent", -"porter", -"portia", -"portico", -"portify", -"portio", -"portion", -"portlet", -"portly", -"portman", -"porto", -"portray", -"portway", -"porty", -"porule", -"porus", -"pory", -"posca", -"pose", -"poser", -"poseur", -"posey", -"posh", -"posing", -"posit", -"positor", -"positum", -"posnet", -"posole", -"poss", -"posse", -"possess", -"posset", -"possum", -"post", -"postage", -"postal", -"postbag", -"postbox", -"postboy", -"posted", -"posteen", -"poster", -"postern", -"postfix", -"postic", -"postil", -"posting", -"postman", -"posture", -"postwar", -"posy", -"pot", -"potable", -"potamic", -"potash", -"potass", -"potassa", -"potate", -"potato", -"potator", -"potbank", -"potboil", -"potboy", -"potch", -"potcher", -"potdar", -"pote", -"poteen", -"potence", -"potency", -"potent", -"poter", -"poteye", -"potful", -"potgirl", -"potgun", -"pothead", -"potheen", -"pother", -"potherb", -"pothery", -"pothole", -"pothook", -"pothunt", -"potifer", -"potion", -"potleg", -"potlid", -"potlike", -"potluck", -"potman", -"potong", -"potoo", -"potoroo", -"potpie", -"potrack", -"pott", -"pottage", -"pottagy", -"pottah", -"potted", -"potter", -"pottery", -"potting", -"pottle", -"pottled", -"potto", -"potty", -"potware", -"potwork", -"potwort", -"pouce", -"poucer", -"poucey", -"pouch", -"pouched", -"pouchy", -"pouf", -"poulard", -"poulp", -"poulpe", -"poult", -"poulter", -"poultry", -"pounamu", -"pounce", -"pounced", -"pouncer", -"pouncet", -"pound", -"poundal", -"pounder", -"pour", -"pourer", -"pourie", -"pouring", -"pouser", -"pout", -"pouter", -"poutful", -"pouting", -"pouty", -"poverty", -"pow", -"powder", -"powdery", -"powdike", -"powdry", -"power", -"powered", -"powitch", -"pownie", -"powwow", -"pox", -"poxy", -"poy", -"poyou", -"praam", -"prabble", -"prabhu", -"practic", -"prad", -"praecox", -"praetor", -"prairie", -"praise", -"praiser", -"prajna", -"praline", -"pram", -"prana", -"prance", -"prancer", -"prancy", -"prank", -"pranked", -"pranker", -"prankle", -"pranky", -"prase", -"prasine", -"prasoid", -"prastha", -"prat", -"pratal", -"prate", -"prater", -"pratey", -"prating", -"prattle", -"prattly", -"prau", -"pravity", -"prawn", -"prawner", -"prawny", -"praxis", -"pray", -"praya", -"prayer", -"prayful", -"praying", -"preach", -"preachy", -"preacid", -"preact", -"preaged", -"preally", -"preanal", -"prearm", -"preaver", -"prebake", -"prebend", -"prebid", -"prebill", -"preboil", -"preborn", -"preburn", -"precant", -"precary", -"precast", -"precava", -"precede", -"precent", -"precept", -"preces", -"precess", -"precipe", -"precis", -"precise", -"precite", -"precoil", -"precook", -"precool", -"precopy", -"precox", -"precure", -"precut", -"precyst", -"predamn", -"predark", -"predata", -"predate", -"predawn", -"preday", -"predefy", -"predeny", -"predial", -"predict", -"prediet", -"predine", -"predoom", -"predraw", -"predry", -"predusk", -"preen", -"preener", -"preeze", -"prefab", -"preface", -"prefect", -"prefer", -"prefine", -"prefix", -"prefool", -"preform", -"pregain", -"pregust", -"prehaps", -"preheal", -"preheat", -"prehend", -"preidea", -"preknit", -"preknow", -"prelacy", -"prelate", -"prelect", -"prelim", -"preloan", -"preloss", -"prelude", -"premake", -"premate", -"premial", -"premier", -"premise", -"premiss", -"premium", -"premix", -"premold", -"premove", -"prename", -"prender", -"prendre", -"preomit", -"preopen", -"preoral", -"prep", -"prepare", -"prepave", -"prepay", -"prepink", -"preplan", -"preplot", -"prepose", -"prepuce", -"prepupa", -"prerent", -"prerich", -"prerupt", -"presage", -"presay", -"preseal", -"presee", -"presell", -"present", -"preses", -"preset", -"preship", -"preshow", -"preside", -"presift", -"presign", -"prespur", -"press", -"pressel", -"presser", -"pressor", -"prest", -"prester", -"presto", -"presume", -"pretan", -"pretell", -"pretend", -"pretest", -"pretext", -"pretire", -"pretone", -"pretry", -"pretty", -"pretzel", -"prevail", -"prevene", -"prevent", -"preverb", -"preveto", -"previde", -"preview", -"previse", -"prevoid", -"prevote", -"prevue", -"prewar", -"prewarn", -"prewash", -"prewhip", -"prewire", -"prewrap", -"prexy", -"prey", -"preyer", -"preyful", -"prezone", -"price", -"priced", -"pricer", -"prich", -"prick", -"pricked", -"pricker", -"pricket", -"prickle", -"prickly", -"pricks", -"pricky", -"pride", -"pridian", -"priding", -"pridy", -"pried", -"prier", -"priest", -"prig", -"prigdom", -"prigger", -"prigman", -"prill", -"prim", -"prima", -"primacy", -"primage", -"primal", -"primar", -"primary", -"primate", -"prime", -"primely", -"primer", -"primero", -"primine", -"priming", -"primly", -"primost", -"primp", -"primsie", -"primula", -"primus", -"primy", -"prince", -"princox", -"prine", -"pringle", -"prink", -"prinker", -"prinkle", -"prinky", -"print", -"printed", -"printer", -"prion", -"prionid", -"prior", -"prioral", -"priorly", -"priory", -"prisage", -"prisal", -"priscan", -"prism", -"prismal", -"prismed", -"prismy", -"prison", -"priss", -"prissy", -"pritch", -"prithee", -"prius", -"privacy", -"privant", -"private", -"privet", -"privily", -"privity", -"privy", -"prize", -"prizer", -"prizery", -"pro", -"proa", -"proal", -"proarmy", -"prob", -"probabl", -"probal", -"probang", -"probant", -"probate", -"probe", -"probeer", -"prober", -"probity", -"problem", -"procarp", -"proceed", -"process", -"proctal", -"proctor", -"procure", -"prod", -"prodder", -"proddle", -"prodigy", -"produce", -"product", -"proem", -"proetid", -"prof", -"profane", -"profert", -"profess", -"proffer", -"profile", -"profit", -"profuse", -"prog", -"progeny", -"progger", -"progne", -"program", -"project", -"proke", -"proker", -"prolan", -"prolate", -"proleg", -"prolify", -"proline", -"prolix", -"prolong", -"prolyl", -"promic", -"promise", -"promote", -"prompt", -"pronaos", -"pronate", -"pronavy", -"prone", -"pronely", -"proneur", -"prong", -"pronged", -"pronger", -"pronic", -"pronoun", -"pronpl", -"pronto", -"pronuba", -"proo", -"proof", -"proofer", -"proofy", -"prop", -"propago", -"propale", -"propane", -"propend", -"propene", -"proper", -"prophet", -"propine", -"proplex", -"propone", -"propons", -"propose", -"propoxy", -"propper", -"props", -"propupa", -"propyl", -"propyne", -"prorata", -"prorate", -"prore", -"prorean", -"prorsad", -"prorsal", -"prosaic", -"prosar", -"prose", -"prosect", -"proser", -"prosify", -"prosily", -"prosing", -"prosish", -"prosist", -"proso", -"prosode", -"prosody", -"prosoma", -"prosper", -"pross", -"prossy", -"prosy", -"protax", -"prote", -"protea", -"protead", -"protean", -"protect", -"protege", -"proteic", -"protein", -"protend", -"protest", -"protext", -"prothyl", -"protide", -"protist", -"protium", -"proto", -"protoma", -"protome", -"proton", -"protone", -"protore", -"protyl", -"protyle", -"protype", -"proudly", -"provand", -"provant", -"prove", -"provect", -"proved", -"proven", -"prover", -"proverb", -"provide", -"provine", -"proving", -"proviso", -"provoke", -"provost", -"prow", -"prowar", -"prowed", -"prowess", -"prowl", -"prowler", -"proxeny", -"proximo", -"proxy", -"proxysm", -"prozone", -"prude", -"prudely", -"prudent", -"prudery", -"prudish", -"prudist", -"prudity", -"pruh", -"prunase", -"prune", -"prunell", -"pruner", -"pruning", -"prunt", -"prunted", -"prurigo", -"prussic", -"prut", -"prutah", -"pry", -"pryer", -"prying", -"pryler", -"pryse", -"prytany", -"psalis", -"psalm", -"psalmic", -"psalmy", -"psaloid", -"psalter", -"psaltes", -"pschent", -"pseudo", -"psha", -"pshaw", -"psi", -"psiloi", -"psoadic", -"psoas", -"psoatic", -"psocid", -"psocine", -"psoitis", -"psora", -"psoric", -"psoroid", -"psorous", -"pst", -"psych", -"psychal", -"psyche", -"psychic", -"psychid", -"psychon", -"psykter", -"psylla", -"psyllid", -"ptarmic", -"ptereal", -"pteric", -"pterion", -"pteroid", -"pteroma", -"pteryla", -"ptinid", -"ptinoid", -"ptisan", -"ptomain", -"ptosis", -"ptotic", -"ptyalin", -"ptyxis", -"pu", -"pua", -"puan", -"pub", -"pubal", -"pubble", -"puberal", -"puberty", -"pubes", -"pubian", -"pubic", -"pubis", -"public", -"publish", -"puccoon", -"puce", -"pucelle", -"puchero", -"puck", -"pucka", -"pucker", -"puckery", -"puckish", -"puckle", -"puckrel", -"pud", -"puddee", -"pudder", -"pudding", -"puddle", -"puddled", -"puddler", -"puddly", -"puddock", -"puddy", -"pudency", -"pudenda", -"pudent", -"pudge", -"pudgily", -"pudgy", -"pudiano", -"pudic", -"pudical", -"pudsey", -"pudsy", -"pudu", -"pueblo", -"puerer", -"puerile", -"puerman", -"puff", -"puffed", -"puffer", -"puffery", -"puffily", -"puffin", -"puffing", -"pufflet", -"puffwig", -"puffy", -"pug", -"pugged", -"pugger", -"puggi", -"pugging", -"puggish", -"puggle", -"puggree", -"puggy", -"pugh", -"pugil", -"pugman", -"pugmill", -"puisne", -"puist", -"puistie", -"puja", -"puka", -"pukatea", -"puke", -"pukeko", -"puker", -"pukish", -"pukras", -"puku", -"puky", -"pul", -"pulahan", -"pulasan", -"pule", -"pulegol", -"puler", -"puli", -"pulicat", -"pulicid", -"puling", -"pulish", -"pulk", -"pulka", -"pull", -"pulldoo", -"pullen", -"puller", -"pullery", -"pullet", -"pulley", -"pulli", -"pullus", -"pulp", -"pulpal", -"pulper", -"pulpify", -"pulpily", -"pulpit", -"pulpous", -"pulpy", -"pulque", -"pulsant", -"pulsate", -"pulse", -"pulsion", -"pulsive", -"pulton", -"pulu", -"pulvic", -"pulvil", -"pulvino", -"pulwar", -"puly", -"puma", -"pumice", -"pumiced", -"pumicer", -"pummel", -"pummice", -"pump", -"pumpage", -"pumper", -"pumpkin", -"pumple", -"pumpman", -"pun", -"puna", -"punaise", -"punalua", -"punatoo", -"punch", -"puncher", -"punchy", -"punct", -"punctal", -"punctum", -"pundit", -"pundita", -"pundum", -"puneca", -"pung", -"punga", -"pungar", -"pungent", -"punger", -"pungey", -"pungi", -"pungle", -"pungled", -"punicin", -"punily", -"punish", -"punjum", -"punk", -"punkah", -"punkie", -"punky", -"punless", -"punlet", -"punnage", -"punner", -"punnet", -"punnic", -"punster", -"punt", -"punta", -"puntal", -"puntel", -"punter", -"punti", -"puntil", -"puntist", -"punto", -"puntout", -"punty", -"puny", -"punyish", -"punyism", -"pup", -"pupa", -"pupal", -"pupate", -"pupelo", -"pupil", -"pupilar", -"pupiled", -"pupoid", -"puppet", -"puppify", -"puppily", -"puppy", -"pupulo", -"pupunha", -"pur", -"purana", -"puranic", -"puraque", -"purdah", -"purdy", -"pure", -"pured", -"puree", -"purely", -"purer", -"purfle", -"purfled", -"purfler", -"purfly", -"purga", -"purge", -"purger", -"purgery", -"purging", -"purify", -"purine", -"puriri", -"purism", -"purist", -"purity", -"purl", -"purler", -"purlieu", -"purlin", -"purlman", -"purloin", -"purpart", -"purple", -"purply", -"purport", -"purpose", -"purpura", -"purpure", -"purr", -"purre", -"purree", -"purreic", -"purrel", -"purrer", -"purring", -"purrone", -"purry", -"purse", -"pursed", -"purser", -"pursily", -"purslet", -"pursley", -"pursual", -"pursue", -"pursuer", -"pursuit", -"pursy", -"purusha", -"purvey", -"purview", -"purvoe", -"pus", -"push", -"pusher", -"pushful", -"pushing", -"pushpin", -"puss", -"pusscat", -"pussley", -"pussy", -"pustule", -"put", -"putage", -"putamen", -"putback", -"putchen", -"putcher", -"puteal", -"putelee", -"puther", -"puthery", -"putid", -"putidly", -"putlog", -"putois", -"putrefy", -"putrid", -"putt", -"puttee", -"putter", -"puttier", -"puttock", -"putty", -"puture", -"puxy", -"puzzle", -"puzzled", -"puzzler", -"pya", -"pyal", -"pyche", -"pycnia", -"pycnial", -"pycnid", -"pycnite", -"pycnium", -"pyelic", -"pyemia", -"pyemic", -"pygal", -"pygarg", -"pygidid", -"pygmoid", -"pygmy", -"pygofer", -"pygopod", -"pyic", -"pyin", -"pyjama", -"pyke", -"pyknic", -"pyla", -"pylar", -"pylic", -"pylon", -"pyloric", -"pylorus", -"pyocele", -"pyocyst", -"pyocyte", -"pyoid", -"pyosis", -"pyr", -"pyral", -"pyralid", -"pyralis", -"pyramid", -"pyran", -"pyranyl", -"pyre", -"pyrena", -"pyrene", -"pyrenic", -"pyrenin", -"pyretic", -"pyrex", -"pyrexia", -"pyrexic", -"pyrgom", -"pyridic", -"pyridyl", -"pyrite", -"pyrites", -"pyritic", -"pyro", -"pyrogen", -"pyroid", -"pyrone", -"pyrope", -"pyropen", -"pyropus", -"pyrosis", -"pyrotic", -"pyrrhic", -"pyrrol", -"pyrrole", -"pyrroyl", -"pyrryl", -"pyruvic", -"pyruvil", -"pyruvyl", -"python", -"pyuria", -"pyvuril", -"pyx", -"pyxides", -"pyxie", -"pyxis", -"q", -"qasida", -"qere", -"qeri", -"qintar", -"qoph", -"qua", -"quab", -"quabird", -"quachil", -"quack", -"quackle", -"quacky", -"quad", -"quadded", -"quaddle", -"quadra", -"quadral", -"quadrat", -"quadric", -"quadrum", -"quaedam", -"quaff", -"quaffer", -"quag", -"quagga", -"quaggle", -"quaggy", -"quahog", -"quail", -"quaily", -"quaint", -"quake", -"quaker", -"quaking", -"quaky", -"quale", -"qualify", -"quality", -"qualm", -"qualmy", -"quan", -"quandy", -"quannet", -"quant", -"quanta", -"quantic", -"quantum", -"quar", -"quare", -"quark", -"quarl", -"quarle", -"quarred", -"quarrel", -"quarry", -"quart", -"quartan", -"quarter", -"quartet", -"quartic", -"quarto", -"quartz", -"quartzy", -"quash", -"quashey", -"quashy", -"quasi", -"quasky", -"quassin", -"quat", -"quata", -"quatch", -"quatern", -"quaters", -"quatral", -"quatre", -"quatrin", -"quattie", -"quatuor", -"quauk", -"quave", -"quaver", -"quavery", -"quaw", -"quawk", -"quay", -"quayage", -"quayful", -"quayman", -"qubba", -"queach", -"queachy", -"queak", -"queal", -"quean", -"queasom", -"queasy", -"quedful", -"queechy", -"queen", -"queenly", -"queer", -"queerer", -"queerly", -"queery", -"queest", -"queet", -"queeve", -"quegh", -"quei", -"quelch", -"quell", -"queller", -"quemado", -"queme", -"quemely", -"quench", -"quercic", -"quercin", -"querent", -"querier", -"querist", -"querken", -"querl", -"quern", -"quernal", -"query", -"quest", -"quester", -"questor", -"quet", -"quetch", -"quetzal", -"queue", -"quey", -"quiapo", -"quib", -"quibble", -"quiblet", -"quica", -"quick", -"quicken", -"quickie", -"quickly", -"quid", -"quidder", -"quiddit", -"quiddle", -"quiesce", -"quiet", -"quieten", -"quieter", -"quietly", -"quietus", -"quiff", -"quila", -"quiles", -"quilkin", -"quill", -"quillai", -"quilled", -"quiller", -"quillet", -"quilly", -"quilt", -"quilted", -"quilter", -"quin", -"quina", -"quinary", -"quinate", -"quince", -"quinch", -"quinia", -"quinic", -"quinin", -"quinina", -"quinine", -"quinism", -"quinite", -"quinize", -"quink", -"quinnat", -"quinnet", -"quinoa", -"quinoid", -"quinol", -"quinone", -"quinova", -"quinoyl", -"quinse", -"quinsy", -"quint", -"quintad", -"quintal", -"quintan", -"quinte", -"quintet", -"quintic", -"quintin", -"quinto", -"quinton", -"quintus", -"quinyl", -"quinze", -"quip", -"quipful", -"quipo", -"quipper", -"quippy", -"quipu", -"quira", -"quire", -"quirk", -"quirky", -"quirl", -"quirt", -"quis", -"quisby", -"quiscos", -"quisle", -"quit", -"quitch", -"quite", -"quits", -"quitted", -"quitter", -"quittor", -"quiver", -"quivery", -"quiz", -"quizzee", -"quizzer", -"quizzy", -"quo", -"quod", -"quoin", -"quoined", -"quoit", -"quoiter", -"quoits", -"quondam", -"quoniam", -"quop", -"quorum", -"quot", -"quota", -"quote", -"quotee", -"quoter", -"quoth", -"quotha", -"quotity", -"quotum", -"r", -"ra", -"raad", -"raash", -"rab", -"raband", -"rabanna", -"rabat", -"rabatte", -"rabbet", -"rabbi", -"rabbin", -"rabbit", -"rabbity", -"rabble", -"rabbler", -"rabboni", -"rabic", -"rabid", -"rabidly", -"rabies", -"rabific", -"rabinet", -"rabitic", -"raccoon", -"raccroc", -"race", -"raceme", -"racemed", -"racemic", -"racer", -"raceway", -"rach", -"rache", -"rachial", -"rachis", -"racial", -"racily", -"racing", -"racism", -"racist", -"rack", -"rackan", -"racker", -"racket", -"rackett", -"rackety", -"rackful", -"racking", -"rackle", -"rackway", -"racloir", -"racon", -"racoon", -"racy", -"rad", -"rada", -"radar", -"raddle", -"radial", -"radiale", -"radian", -"radiant", -"radiate", -"radical", -"radicel", -"radices", -"radicle", -"radii", -"radio", -"radiode", -"radish", -"radium", -"radius", -"radix", -"radman", -"radome", -"radon", -"radula", -"raff", -"raffe", -"raffee", -"raffery", -"raffia", -"raffing", -"raffish", -"raffle", -"raffler", -"raft", -"raftage", -"rafter", -"raftman", -"rafty", -"rag", -"raga", -"rage", -"rageful", -"rageous", -"rager", -"ragfish", -"ragged", -"raggedy", -"raggee", -"ragger", -"raggery", -"raggety", -"raggil", -"raggily", -"ragging", -"raggle", -"raggled", -"raggy", -"raging", -"raglan", -"raglet", -"raglin", -"ragman", -"ragout", -"ragshag", -"ragtag", -"ragtime", -"ragule", -"raguly", -"ragweed", -"ragwort", -"rah", -"rahdar", -"raia", -"raid", -"raider", -"rail", -"railage", -"railer", -"railing", -"railly", -"railman", -"railway", -"raiment", -"rain", -"rainbow", -"rainer", -"rainful", -"rainily", -"rainy", -"raioid", -"rais", -"raise", -"raised", -"raiser", -"raisin", -"raising", -"raisiny", -"raj", -"raja", -"rajah", -"rakan", -"rake", -"rakeage", -"rakeful", -"raker", -"rakery", -"rakh", -"raki", -"rakily", -"raking", -"rakish", -"rakit", -"raku", -"rallier", -"ralline", -"rally", -"ralph", -"ram", -"ramada", -"ramage", -"ramal", -"ramanas", -"ramass", -"ramate", -"rambeh", -"ramble", -"rambler", -"rambong", -"rame", -"rameal", -"ramed", -"ramekin", -"rament", -"rameous", -"ramet", -"ramex", -"ramhead", -"ramhood", -"rami", -"ramie", -"ramify", -"ramlike", -"ramline", -"rammack", -"rammel", -"rammer", -"rammish", -"rammy", -"ramose", -"ramous", -"ramp", -"rampage", -"rampant", -"rampart", -"ramped", -"ramper", -"rampick", -"rampike", -"ramping", -"rampion", -"rampire", -"rampler", -"ramplor", -"ramrace", -"ramrod", -"ramsch", -"ramson", -"ramstam", -"ramtil", -"ramular", -"ramule", -"ramulus", -"ramus", -"ran", -"rana", -"ranal", -"rance", -"rancel", -"rancer", -"ranch", -"ranche", -"rancher", -"rancho", -"rancid", -"rancor", -"rand", -"randan", -"randem", -"rander", -"randing", -"randir", -"randle", -"random", -"randy", -"rane", -"rang", -"range", -"ranged", -"ranger", -"rangey", -"ranging", -"rangle", -"rangler", -"rangy", -"rani", -"ranid", -"ranine", -"rank", -"ranked", -"ranker", -"rankish", -"rankle", -"rankly", -"rann", -"rannel", -"ranny", -"ransack", -"ransel", -"ransom", -"rant", -"rantan", -"ranter", -"ranting", -"rantock", -"ranty", -"ranula", -"ranular", -"rap", -"rape", -"rapeful", -"raper", -"raphany", -"raphe", -"raphide", -"raphis", -"rapic", -"rapid", -"rapidly", -"rapier", -"rapillo", -"rapine", -"rapiner", -"raping", -"rapinic", -"rapist", -"raploch", -"rappage", -"rappe", -"rappel", -"rapper", -"rapping", -"rappist", -"rapport", -"rapt", -"raptly", -"raptor", -"raptril", -"rapture", -"raptury", -"raptus", -"rare", -"rarebit", -"rarefy", -"rarely", -"rarish", -"rarity", -"ras", -"rasa", -"rasant", -"rascal", -"rasceta", -"rase", -"rasen", -"raser", -"rasgado", -"rash", -"rasher", -"rashful", -"rashing", -"rashly", -"rasion", -"rasp", -"rasped", -"rasper", -"rasping", -"raspish", -"raspite", -"raspy", -"rasse", -"rassle", -"raster", -"rastik", -"rastle", -"rasure", -"rat", -"rata", -"ratable", -"ratably", -"ratafee", -"ratafia", -"ratal", -"ratbite", -"ratch", -"ratchel", -"ratcher", -"ratchet", -"rate", -"rated", -"ratel", -"rater", -"ratfish", -"rath", -"rathe", -"rathed", -"rathely", -"rather", -"rathest", -"rathite", -"rathole", -"ratify", -"ratine", -"rating", -"ratio", -"ration", -"ratite", -"ratlike", -"ratline", -"ratoon", -"rattage", -"rattail", -"rattan", -"ratteen", -"ratten", -"ratter", -"rattery", -"ratti", -"rattish", -"rattle", -"rattled", -"rattler", -"rattles", -"rattly", -"ratton", -"rattrap", -"ratty", -"ratwa", -"ratwood", -"raucid", -"raucity", -"raucous", -"raught", -"rauk", -"raukle", -"rauli", -"raun", -"raunge", -"raupo", -"rauque", -"ravage", -"ravager", -"rave", -"ravel", -"raveler", -"ravelin", -"ravelly", -"raven", -"ravener", -"ravenry", -"ravens", -"raver", -"ravin", -"ravine", -"ravined", -"raviney", -"raving", -"ravioli", -"ravish", -"ravison", -"raw", -"rawhead", -"rawhide", -"rawish", -"rawness", -"rax", -"ray", -"raya", -"rayage", -"rayed", -"rayful", -"rayless", -"raylet", -"rayon", -"raze", -"razee", -"razer", -"razoo", -"razor", -"razz", -"razzia", -"razzly", -"re", -"rea", -"reaal", -"reabuse", -"reach", -"reacher", -"reachy", -"react", -"reactor", -"read", -"readapt", -"readd", -"reader", -"readily", -"reading", -"readmit", -"readopt", -"readorn", -"ready", -"reagent", -"reagin", -"reagree", -"reak", -"real", -"realarm", -"reales", -"realest", -"realgar", -"realign", -"realism", -"realist", -"reality", -"realive", -"realize", -"reallot", -"reallow", -"really", -"realm", -"realter", -"realtor", -"realty", -"ream", -"reamage", -"reamass", -"reamend", -"reamer", -"reamuse", -"reamy", -"reannex", -"reannoy", -"reanvil", -"reap", -"reaper", -"reapply", -"rear", -"rearer", -"reargue", -"rearise", -"rearm", -"rearray", -"reask", -"reason", -"reassay", -"reasty", -"reasy", -"reatus", -"reaudit", -"reavail", -"reave", -"reaver", -"reavoid", -"reavow", -"reawait", -"reawake", -"reaward", -"reaware", -"reb", -"rebab", -"reback", -"rebag", -"rebait", -"rebake", -"rebale", -"reban", -"rebar", -"rebase", -"rebasis", -"rebate", -"rebater", -"rebathe", -"rebato", -"rebawl", -"rebear", -"rebeat", -"rebec", -"rebeck", -"rebed", -"rebeg", -"rebeget", -"rebegin", -"rebel", -"rebelly", -"rebend", -"rebeset", -"rebia", -"rebias", -"rebid", -"rebill", -"rebind", -"rebirth", -"rebite", -"reblade", -"reblame", -"reblast", -"reblend", -"rebless", -"reblock", -"rebloom", -"reblot", -"reblow", -"reblue", -"rebluff", -"reboant", -"reboard", -"reboast", -"rebob", -"reboil", -"reboise", -"rebold", -"rebolt", -"rebone", -"rebook", -"rebop", -"rebore", -"reborn", -"rebound", -"rebox", -"rebrace", -"rebraid", -"rebrand", -"rebreed", -"rebrew", -"rebribe", -"rebrick", -"rebring", -"rebrown", -"rebrush", -"rebud", -"rebuff", -"rebuild", -"rebuilt", -"rebuke", -"rebuker", -"rebulk", -"rebunch", -"rebuoy", -"reburn", -"reburst", -"rebury", -"rebus", -"rebush", -"rebusy", -"rebut", -"rebute", -"rebuy", -"recable", -"recage", -"recalk", -"recall", -"recant", -"recap", -"recarry", -"recart", -"recarve", -"recase", -"recash", -"recast", -"recatch", -"recce", -"recco", -"reccy", -"recede", -"receder", -"receipt", -"receive", -"recency", -"recense", -"recent", -"recept", -"recess", -"rechafe", -"rechain", -"rechal", -"rechant", -"rechaos", -"rechar", -"rechase", -"rechaw", -"recheat", -"recheck", -"recheer", -"rechew", -"rechip", -"rechuck", -"rechurn", -"recipe", -"recital", -"recite", -"reciter", -"reck", -"reckla", -"reckon", -"reclaim", -"reclama", -"reclang", -"reclasp", -"reclass", -"reclean", -"reclear", -"reclimb", -"recline", -"reclose", -"recluse", -"recoach", -"recoal", -"recoast", -"recoat", -"recock", -"recoct", -"recode", -"recoil", -"recoin", -"recoke", -"recolor", -"recomb", -"recon", -"recook", -"recool", -"recopy", -"record", -"recork", -"recount", -"recoup", -"recover", -"recramp", -"recrank", -"recrate", -"recrew", -"recroon", -"recrop", -"recross", -"recrowd", -"recrown", -"recruit", -"recrush", -"rect", -"recta", -"rectal", -"recti", -"rectify", -"rection", -"recto", -"rector", -"rectory", -"rectrix", -"rectum", -"rectus", -"recur", -"recure", -"recurl", -"recurse", -"recurve", -"recuse", -"recut", -"recycle", -"red", -"redact", -"redan", -"redare", -"redarn", -"redart", -"redate", -"redaub", -"redawn", -"redback", -"redbait", -"redbill", -"redbird", -"redbone", -"redbuck", -"redbud", -"redcap", -"redcoat", -"redd", -"redden", -"redder", -"redding", -"reddish", -"reddock", -"reddy", -"rede", -"redeal", -"redebit", -"redeck", -"redeed", -"redeem", -"redefer", -"redefy", -"redeify", -"redelay", -"redeny", -"redeye", -"redfin", -"redfish", -"redfoot", -"redhead", -"redhoop", -"redia", -"redient", -"redig", -"redip", -"redive", -"redleg", -"redlegs", -"redly", -"redness", -"redo", -"redock", -"redoom", -"redoubt", -"redound", -"redowa", -"redox", -"redpoll", -"redraft", -"redrag", -"redrape", -"redraw", -"redream", -"redress", -"redrill", -"redrive", -"redroot", -"redry", -"redsear", -"redskin", -"redtab", -"redtail", -"redtop", -"redub", -"reduce", -"reduced", -"reducer", -"reduct", -"redue", -"redux", -"redward", -"redware", -"redweed", -"redwing", -"redwood", -"redye", -"ree", -"reechy", -"reed", -"reeded", -"reeden", -"reeder", -"reedily", -"reeding", -"reedish", -"reedman", -"reedy", -"reef", -"reefer", -"reefing", -"reefy", -"reek", -"reeker", -"reeky", -"reel", -"reeled", -"reeler", -"reem", -"reeming", -"reemish", -"reen", -"reenge", -"reeper", -"reese", -"reeshle", -"reesk", -"reesle", -"reest", -"reester", -"reestle", -"reesty", -"reet", -"reetam", -"reetle", -"reeve", -"ref", -"reface", -"refall", -"refan", -"refavor", -"refect", -"refeed", -"refeel", -"refeign", -"refel", -"refence", -"refer", -"referee", -"refetch", -"refight", -"refill", -"refilm", -"refind", -"refine", -"refined", -"refiner", -"refire", -"refit", -"refix", -"reflag", -"reflame", -"reflash", -"reflate", -"reflect", -"reflee", -"reflex", -"refling", -"refloat", -"reflog", -"reflood", -"refloor", -"reflow", -"reflush", -"reflux", -"refly", -"refocus", -"refold", -"refont", -"refool", -"refoot", -"reforce", -"reford", -"reforge", -"reform", -"refound", -"refract", -"refrain", -"reframe", -"refresh", -"refront", -"reft", -"refuel", -"refuge", -"refugee", -"refulge", -"refund", -"refurl", -"refusal", -"refuse", -"refuser", -"refutal", -"refute", -"refuter", -"reg", -"regain", -"regal", -"regale", -"regaler", -"regalia", -"regally", -"regard", -"regatta", -"regauge", -"regency", -"regent", -"reges", -"reget", -"regia", -"regift", -"regild", -"regill", -"regime", -"regimen", -"regin", -"reginal", -"region", -"regive", -"reglair", -"reglaze", -"regle", -"reglet", -"regloss", -"reglove", -"reglow", -"reglue", -"regma", -"regnal", -"regnant", -"regorge", -"regrade", -"regraft", -"regrant", -"regrasp", -"regrass", -"regrate", -"regrede", -"regreen", -"regreet", -"regress", -"regret", -"regrind", -"regrip", -"regroup", -"regrow", -"reguard", -"reguide", -"regula", -"regular", -"reguli", -"regulus", -"regur", -"regurge", -"regush", -"reh", -"rehair", -"rehale", -"rehang", -"reharm", -"rehash", -"rehaul", -"rehead", -"reheal", -"reheap", -"rehear", -"reheat", -"rehedge", -"reheel", -"rehoe", -"rehoist", -"rehonor", -"rehood", -"rehook", -"rehoop", -"rehouse", -"rehung", -"reif", -"reify", -"reign", -"reim", -"reimage", -"reimpel", -"reimply", -"rein", -"reina", -"reincur", -"reindue", -"reinfer", -"reins", -"reinter", -"reis", -"reissue", -"reit", -"reitbok", -"reiter", -"reiver", -"rejail", -"reject", -"rejerk", -"rejoice", -"rejoin", -"rejolt", -"rejudge", -"rekick", -"rekill", -"reking", -"rekiss", -"reknit", -"reknow", -"rel", -"relabel", -"relace", -"relade", -"reladen", -"relais", -"relamp", -"reland", -"relap", -"relapse", -"relast", -"relata", -"relatch", -"relate", -"related", -"relater", -"relator", -"relatum", -"relax", -"relaxed", -"relaxer", -"relay", -"relbun", -"relead", -"releap", -"relearn", -"release", -"relend", -"relent", -"relet", -"relevel", -"relevy", -"reliant", -"relic", -"relick", -"relict", -"relief", -"relier", -"relieve", -"relievo", -"relift", -"relight", -"relime", -"relimit", -"reline", -"reliner", -"relink", -"relish", -"relishy", -"relist", -"relive", -"reload", -"reloan", -"relock", -"relodge", -"relook", -"relose", -"relost", -"relot", -"relove", -"relower", -"reluct", -"relume", -"rely", -"remade", -"remail", -"remain", -"remains", -"remake", -"remaker", -"reman", -"remand", -"remanet", -"remap", -"remarch", -"remark", -"remarry", -"remask", -"remass", -"remast", -"rematch", -"remble", -"remeant", -"remede", -"remedy", -"remeet", -"remelt", -"remend", -"remerge", -"remetal", -"remex", -"remica", -"remicle", -"remiges", -"remill", -"remimic", -"remind", -"remint", -"remiped", -"remise", -"remiss", -"remit", -"remix", -"remnant", -"remock", -"remodel", -"remold", -"remop", -"remora", -"remord", -"remorse", -"remote", -"remould", -"remount", -"removal", -"remove", -"removed", -"remover", -"renable", -"renably", -"renail", -"renal", -"rename", -"rend", -"render", -"reneg", -"renege", -"reneger", -"renegue", -"renerve", -"renes", -"renet", -"renew", -"renewal", -"renewer", -"renin", -"renish", -"renk", -"renky", -"renne", -"rennet", -"rennin", -"renown", -"rent", -"rentage", -"rental", -"rented", -"rentee", -"renter", -"renvoi", -"renvoy", -"reoccur", -"reoffer", -"reoil", -"reomit", -"reopen", -"reorder", -"reown", -"rep", -"repace", -"repack", -"repage", -"repaint", -"repair", -"repale", -"repand", -"repanel", -"repaper", -"repark", -"repass", -"repast", -"repaste", -"repatch", -"repave", -"repawn", -"repay", -"repayal", -"repeal", -"repeat", -"repeg", -"repel", -"repen", -"repent", -"repew", -"rephase", -"repic", -"repick", -"repiece", -"repile", -"repin", -"repine", -"repiner", -"repipe", -"repique", -"repitch", -"repkie", -"replace", -"replait", -"replan", -"replane", -"replant", -"replate", -"replay", -"replead", -"repleat", -"replete", -"replevy", -"replica", -"replier", -"replod", -"replot", -"replow", -"replum", -"replume", -"reply", -"repoint", -"repoll", -"repolon", -"repone", -"repope", -"report", -"reposal", -"repose", -"reposed", -"reposer", -"reposit", -"repost", -"repot", -"repound", -"repour", -"repp", -"repped", -"repray", -"repress", -"reprice", -"reprime", -"reprint", -"reprise", -"reproof", -"reprove", -"reprune", -"reps", -"reptant", -"reptile", -"repuff", -"repugn", -"repulse", -"repump", -"repurge", -"repute", -"reputed", -"requeen", -"request", -"requiem", -"requin", -"require", -"requit", -"requite", -"requiz", -"requote", -"rerack", -"rerail", -"reraise", -"rerake", -"rerank", -"rerate", -"reread", -"reredos", -"reree", -"rereel", -"rereeve", -"rereign", -"rerent", -"rerig", -"rering", -"rerise", -"rerival", -"rerivet", -"rerob", -"rerobe", -"reroll", -"reroof", -"reroot", -"rerope", -"reroute", -"rerow", -"rerub", -"rerun", -"resaca", -"resack", -"resail", -"resale", -"resalt", -"resaw", -"resawer", -"resay", -"rescan", -"rescind", -"rescore", -"rescrub", -"rescue", -"rescuer", -"reseal", -"reseam", -"reseat", -"resect", -"reseda", -"resee", -"reseed", -"reseek", -"reseise", -"reseize", -"reself", -"resell", -"resend", -"resene", -"resent", -"reserve", -"reset", -"resever", -"resew", -"resex", -"resh", -"reshake", -"reshape", -"reshare", -"reshave", -"reshear", -"reshift", -"reshine", -"reship", -"reshoe", -"reshoot", -"reshun", -"reshunt", -"reshut", -"reside", -"resider", -"residua", -"residue", -"resift", -"resigh", -"resign", -"resile", -"resin", -"resina", -"resiner", -"resing", -"resinic", -"resink", -"resinol", -"resiny", -"resist", -"resize", -"resizer", -"reskin", -"reslash", -"reslate", -"reslay", -"reslide", -"reslot", -"resmell", -"resmelt", -"resmile", -"resnap", -"resnub", -"resoak", -"resoap", -"resoil", -"resole", -"resolve", -"resorb", -"resort", -"resound", -"resow", -"resp", -"respace", -"respade", -"respan", -"respeak", -"respect", -"respell", -"respin", -"respire", -"respite", -"resplit", -"respoke", -"respond", -"respot", -"respray", -"respue", -"ressala", -"ressaut", -"rest", -"restack", -"restaff", -"restain", -"restake", -"restamp", -"restant", -"restart", -"restate", -"restaur", -"resteal", -"resteel", -"resteep", -"restem", -"restep", -"rester", -"restes", -"restful", -"restiad", -"restiff", -"resting", -"restir", -"restis", -"restive", -"restock", -"restore", -"restow", -"restrap", -"restrip", -"restudy", -"restuff", -"resty", -"restyle", -"resuck", -"resue", -"resuing", -"resuit", -"result", -"resume", -"resumer", -"resun", -"resup", -"resurge", -"reswage", -"resward", -"reswarm", -"reswear", -"resweat", -"resweep", -"reswell", -"reswill", -"reswim", -"ret", -"retable", -"retack", -"retag", -"retail", -"retain", -"retake", -"retaker", -"retalk", -"retama", -"retame", -"retan", -"retape", -"retard", -"retare", -"retaste", -"retax", -"retch", -"reteach", -"retell", -"retem", -"retempt", -"retene", -"retent", -"retest", -"rethank", -"rethaw", -"rethe", -"rethink", -"rethrow", -"retia", -"retial", -"retiary", -"reticle", -"retie", -"retier", -"retile", -"retill", -"retime", -"retin", -"retina", -"retinal", -"retinol", -"retinue", -"retip", -"retiral", -"retire", -"retired", -"retirer", -"retoast", -"retold", -"retomb", -"retook", -"retool", -"retooth", -"retort", -"retoss", -"retotal", -"retouch", -"retour", -"retrace", -"retrack", -"retract", -"retrad", -"retrade", -"retrain", -"retral", -"retramp", -"retread", -"retreat", -"retree", -"retrial", -"retrim", -"retrip", -"retrot", -"retrude", -"retrue", -"retrust", -"retry", -"retted", -"retter", -"rettery", -"retting", -"rettory", -"retube", -"retuck", -"retune", -"returf", -"return", -"retuse", -"retwine", -"retwist", -"retying", -"retype", -"retzian", -"reune", -"reunify", -"reunion", -"reunite", -"reurge", -"reuse", -"reutter", -"rev", -"revalue", -"revamp", -"revary", -"reve", -"reveal", -"reveil", -"revel", -"reveler", -"revelly", -"revelry", -"revend", -"revenge", -"revent", -"revenue", -"rever", -"reverb", -"revere", -"revered", -"reverer", -"reverie", -"revers", -"reverse", -"reversi", -"reverso", -"revert", -"revery", -"revest", -"revet", -"revete", -"revie", -"review", -"revile", -"reviler", -"revisal", -"revise", -"revisee", -"reviser", -"revisit", -"revisor", -"revival", -"revive", -"reviver", -"revivor", -"revoice", -"revoke", -"revoker", -"revolt", -"revolve", -"revomit", -"revote", -"revue", -"revuist", -"rewade", -"rewager", -"rewake", -"rewaken", -"rewall", -"reward", -"rewarm", -"rewarn", -"rewash", -"rewater", -"rewave", -"rewax", -"rewayle", -"rewear", -"reweave", -"rewed", -"reweigh", -"reweld", -"rewend", -"rewet", -"rewhelp", -"rewhirl", -"rewiden", -"rewin", -"rewind", -"rewire", -"rewish", -"rewood", -"reword", -"rework", -"rewound", -"rewove", -"rewoven", -"rewrap", -"rewrite", -"rex", -"rexen", -"reyield", -"reyoke", -"reyouth", -"rhabdom", -"rhabdos", -"rhabdus", -"rhagite", -"rhagon", -"rhagose", -"rhamn", -"rhamnal", -"rhason", -"rhatany", -"rhe", -"rhea", -"rhebok", -"rheeboc", -"rheebok", -"rheen", -"rheic", -"rhein", -"rheinic", -"rhema", -"rheme", -"rhenium", -"rheotan", -"rhesian", -"rhesus", -"rhetor", -"rheum", -"rheumed", -"rheumic", -"rheumy", -"rhexis", -"rhinal", -"rhine", -"rhinion", -"rhino", -"rhizine", -"rhizoid", -"rhizoma", -"rhizome", -"rhizote", -"rho", -"rhodic", -"rhoding", -"rhodite", -"rhodium", -"rhomb", -"rhombic", -"rhombos", -"rhombus", -"rhubarb", -"rhumb", -"rhumba", -"rhyme", -"rhymer", -"rhymery", -"rhymic", -"rhymist", -"rhymy", -"rhyptic", -"rhythm", -"rhyton", -"ria", -"rial", -"riancy", -"riant", -"riantly", -"riata", -"rib", -"ribald", -"riband", -"ribat", -"ribband", -"ribbed", -"ribber", -"ribbet", -"ribbing", -"ribble", -"ribbon", -"ribbony", -"ribby", -"ribe", -"ribless", -"riblet", -"riblike", -"ribonic", -"ribose", -"ribskin", -"ribwork", -"ribwort", -"rice", -"ricer", -"ricey", -"rich", -"richdom", -"richen", -"riches", -"richly", -"richt", -"ricin", -"ricine", -"ricinic", -"ricinus", -"rick", -"ricker", -"rickets", -"rickety", -"rickey", -"rickle", -"ricksha", -"ricrac", -"rictal", -"rictus", -"rid", -"ridable", -"ridably", -"riddam", -"riddel", -"ridden", -"ridder", -"ridding", -"riddle", -"riddler", -"ride", -"rideau", -"riden", -"rident", -"rider", -"ridered", -"ridge", -"ridged", -"ridgel", -"ridger", -"ridgil", -"ridging", -"ridgy", -"riding", -"ridotto", -"rie", -"riem", -"riempie", -"rier", -"rife", -"rifely", -"riff", -"riffle", -"riffler", -"rifle", -"rifler", -"riflery", -"rifling", -"rift", -"rifter", -"rifty", -"rig", -"rigbane", -"riggald", -"rigger", -"rigging", -"riggish", -"riggite", -"riggot", -"right", -"righten", -"righter", -"rightle", -"rightly", -"righto", -"righty", -"rigid", -"rigidly", -"rigling", -"rignum", -"rigol", -"rigor", -"rigsby", -"rikisha", -"rikk", -"riksha", -"rikshaw", -"rilawa", -"rile", -"riley", -"rill", -"rillet", -"rillett", -"rillock", -"rilly", -"rim", -"rima", -"rimal", -"rimate", -"rimbase", -"rime", -"rimer", -"rimfire", -"rimland", -"rimless", -"rimmed", -"rimmer", -"rimose", -"rimous", -"rimpi", -"rimple", -"rimrock", -"rimu", -"rimula", -"rimy", -"rinceau", -"rinch", -"rincon", -"rind", -"rinded", -"rindle", -"rindy", -"rine", -"ring", -"ringe", -"ringed", -"ringent", -"ringer", -"ringeye", -"ringing", -"ringite", -"ringle", -"ringlet", -"ringman", -"ringtaw", -"ringy", -"rink", -"rinka", -"rinker", -"rinkite", -"rinner", -"rinse", -"rinser", -"rinsing", -"rio", -"riot", -"rioter", -"rioting", -"riotist", -"riotous", -"riotry", -"rip", -"ripa", -"ripal", -"ripcord", -"ripe", -"ripely", -"ripen", -"ripener", -"riper", -"ripgut", -"ripieno", -"ripier", -"ripost", -"riposte", -"ripper", -"rippet", -"rippier", -"ripping", -"rippit", -"ripple", -"rippler", -"ripplet", -"ripply", -"rippon", -"riprap", -"ripsack", -"ripsaw", -"ripup", -"risala", -"risberm", -"rise", -"risen", -"riser", -"rishi", -"risible", -"risibly", -"rising", -"risk", -"risker", -"riskful", -"riskily", -"riskish", -"risky", -"risp", -"risper", -"risque", -"risquee", -"rissel", -"risser", -"rissle", -"rissoid", -"rist", -"ristori", -"rit", -"rita", -"rite", -"ritling", -"ritual", -"ritzy", -"riva", -"rivage", -"rival", -"rivalry", -"rive", -"rivel", -"rivell", -"riven", -"river", -"rivered", -"riverly", -"rivery", -"rivet", -"riveter", -"riving", -"rivose", -"rivulet", -"rix", -"rixy", -"riyal", -"rizzar", -"rizzle", -"rizzom", -"roach", -"road", -"roadbed", -"roaded", -"roader", -"roading", -"roadite", -"roadman", -"roadway", -"roam", -"roamage", -"roamer", -"roaming", -"roan", -"roanoke", -"roar", -"roarer", -"roaring", -"roast", -"roaster", -"rob", -"robalo", -"roband", -"robber", -"robbery", -"robbin", -"robbing", -"robe", -"rober", -"roberd", -"robin", -"robinet", -"robing", -"robinin", -"roble", -"robomb", -"robot", -"robotry", -"robur", -"robust", -"roc", -"rocher", -"rochet", -"rock", -"rockaby", -"rocker", -"rockery", -"rocket", -"rockety", -"rocking", -"rockish", -"rocklay", -"rocklet", -"rockman", -"rocky", -"rococo", -"rocta", -"rod", -"rodd", -"roddin", -"rodding", -"rode", -"rodent", -"rodeo", -"rodge", -"rodham", -"roding", -"rodless", -"rodlet", -"rodlike", -"rodman", -"rodney", -"rodsman", -"rodster", -"rodwood", -"roe", -"roebuck", -"roed", -"roelike", -"roer", -"roey", -"rog", -"rogan", -"roger", -"roggle", -"rogue", -"roguery", -"roguing", -"roguish", -"rohan", -"rohob", -"rohun", -"rohuna", -"roi", -"roid", -"roil", -"roily", -"roister", -"roit", -"roka", -"roke", -"rokeage", -"rokee", -"rokelay", -"roker", -"rokey", -"roky", -"role", -"roleo", -"roll", -"rolled", -"roller", -"rolley", -"rollick", -"rolling", -"rollix", -"rollmop", -"rollock", -"rollway", -"roloway", -"romaika", -"romaine", -"romal", -"romance", -"romancy", -"romanza", -"romaunt", -"rombos", -"romeite", -"romero", -"rommack", -"romp", -"romper", -"romping", -"rompish", -"rompu", -"rompy", -"roncet", -"ronco", -"rond", -"ronde", -"rondeau", -"rondel", -"rondino", -"rondle", -"rondo", -"rondure", -"rone", -"rongeur", -"ronquil", -"rontgen", -"ronyon", -"rood", -"roodle", -"roof", -"roofage", -"roofer", -"roofing", -"rooflet", -"roofman", -"roofy", -"rooibok", -"rooinek", -"rook", -"rooker", -"rookery", -"rookie", -"rookish", -"rooklet", -"rooky", -"rool", -"room", -"roomage", -"roomed", -"roomer", -"roomful", -"roomie", -"roomily", -"roomlet", -"roomth", -"roomthy", -"roomy", -"roon", -"roosa", -"roost", -"roosted", -"rooster", -"root", -"rootage", -"rootcap", -"rooted", -"rooter", -"rootery", -"rootle", -"rootlet", -"rooty", -"roove", -"ropable", -"rope", -"ropeman", -"roper", -"ropery", -"ropes", -"ropeway", -"ropily", -"roping", -"ropish", -"ropp", -"ropy", -"roque", -"roquer", -"roquet", -"roquist", -"roral", -"roric", -"rorqual", -"rorty", -"rory", -"rosal", -"rosario", -"rosary", -"rosated", -"roscid", -"rose", -"roseal", -"roseate", -"rosebay", -"rosebud", -"rosed", -"roseine", -"rosel", -"roselet", -"rosella", -"roselle", -"roseola", -"roseous", -"rosery", -"roset", -"rosetan", -"rosette", -"rosetty", -"rosetum", -"rosety", -"rosied", -"rosier", -"rosilla", -"rosillo", -"rosily", -"rosin", -"rosiny", -"rosland", -"rosoli", -"rosolic", -"rosolio", -"ross", -"rosser", -"rossite", -"rostel", -"roster", -"rostra", -"rostral", -"rostrum", -"rosular", -"rosy", -"rot", -"rota", -"rotal", -"rotaman", -"rotan", -"rotang", -"rotary", -"rotate", -"rotated", -"rotator", -"rotch", -"rote", -"rotella", -"roter", -"rotge", -"rotgut", -"rother", -"rotifer", -"roto", -"rotor", -"rottan", -"rotten", -"rotter", -"rotting", -"rottle", -"rottock", -"rottolo", -"rotula", -"rotulad", -"rotular", -"rotulet", -"rotulus", -"rotund", -"rotunda", -"rotundo", -"roub", -"roucou", -"roud", -"roue", -"rouelle", -"rouge", -"rougeau", -"rougeot", -"rough", -"roughen", -"rougher", -"roughet", -"roughie", -"roughly", -"roughy", -"rougy", -"rouille", -"rouky", -"roulade", -"rouleau", -"roun", -"rounce", -"rouncy", -"round", -"rounded", -"roundel", -"rounder", -"roundly", -"roundup", -"roundy", -"roup", -"rouper", -"roupet", -"roupily", -"roupit", -"roupy", -"rouse", -"rouser", -"rousing", -"roust", -"rouster", -"rout", -"route", -"router", -"routh", -"routhie", -"routhy", -"routine", -"routing", -"routous", -"rove", -"rover", -"rovet", -"rovetto", -"roving", -"row", -"rowable", -"rowan", -"rowboat", -"rowdily", -"rowdy", -"rowed", -"rowel", -"rowen", -"rower", -"rowet", -"rowing", -"rowlet", -"rowlock", -"rowport", -"rowty", -"rowy", -"rox", -"roxy", -"royal", -"royale", -"royalet", -"royally", -"royalty", -"royet", -"royt", -"rozum", -"ruach", -"ruana", -"rub", -"rubasse", -"rubato", -"rubbed", -"rubber", -"rubbers", -"rubbery", -"rubbing", -"rubbish", -"rubble", -"rubbler", -"rubbly", -"rubdown", -"rubelet", -"rubella", -"rubelle", -"rubeola", -"rubiate", -"rubican", -"rubidic", -"rubied", -"rubific", -"rubify", -"rubine", -"rubious", -"ruble", -"rublis", -"rubor", -"rubric", -"rubrica", -"rubrify", -"ruby", -"ruche", -"ruching", -"ruck", -"rucker", -"ruckle", -"rucksey", -"ruckus", -"rucky", -"ruction", -"rud", -"rudas", -"rudd", -"rudder", -"ruddied", -"ruddily", -"ruddle", -"ruddock", -"ruddy", -"rude", -"rudely", -"ruderal", -"rudesby", -"rudge", -"rudish", -"rudity", -"rue", -"rueful", -"ruelike", -"ruelle", -"ruen", -"ruer", -"ruesome", -"ruewort", -"ruff", -"ruffed", -"ruffer", -"ruffian", -"ruffin", -"ruffle", -"ruffled", -"ruffler", -"ruffly", -"rufous", -"rufter", -"rufus", -"rug", -"ruga", -"rugate", -"rugged", -"rugging", -"ruggle", -"ruggy", -"ruglike", -"rugosa", -"rugose", -"rugous", -"ruin", -"ruinate", -"ruined", -"ruiner", -"ruing", -"ruinous", -"rukh", -"rulable", -"rule", -"ruledom", -"ruler", -"ruling", -"rull", -"ruller", -"rullion", -"rum", -"rumal", -"rumble", -"rumbler", -"rumbly", -"rumbo", -"rumen", -"ruminal", -"rumkin", -"rumless", -"rumly", -"rummage", -"rummagy", -"rummer", -"rummily", -"rummish", -"rummy", -"rumness", -"rumney", -"rumor", -"rumorer", -"rump", -"rumpad", -"rumpade", -"rumple", -"rumply", -"rumpus", -"rumshop", -"run", -"runaway", -"runback", -"runby", -"runch", -"rundale", -"rundle", -"rundlet", -"rune", -"runed", -"runer", -"runfish", -"rung", -"runic", -"runite", -"runkle", -"runkly", -"runless", -"runlet", -"runman", -"runnel", -"runner", -"runnet", -"running", -"runny", -"runoff", -"runout", -"runover", -"runrig", -"runt", -"runted", -"runtee", -"runtish", -"runty", -"runway", -"rupa", -"rupee", -"rupia", -"rupiah", -"rupial", -"rupie", -"rupitic", -"ruptile", -"ruption", -"ruptive", -"rupture", -"rural", -"rurally", -"rurban", -"ruru", -"ruse", -"rush", -"rushed", -"rushen", -"rusher", -"rushing", -"rushlit", -"rushy", -"rusine", -"rusk", -"ruskin", -"rusky", -"rusma", -"rusot", -"ruspone", -"russel", -"russet", -"russety", -"russia", -"russud", -"rust", -"rustful", -"rustic", -"rustily", -"rustle", -"rustler", -"rustly", -"rustre", -"rustred", -"rusty", -"ruswut", -"rut", -"rutate", -"rutch", -"ruth", -"ruther", -"ruthful", -"rutic", -"rutile", -"rutin", -"ruttee", -"rutter", -"ruttish", -"rutty", -"rutyl", -"ruvid", -"rux", -"ryal", -"ryania", -"rybat", -"ryder", -"rye", -"ryen", -"ryme", -"rynd", -"rynt", -"ryot", -"ryotwar", -"rype", -"rypeck", -"s", -"sa", -"saa", -"sab", -"sabalo", -"sabanut", -"sabbat", -"sabbath", -"sabe", -"sabeca", -"sabella", -"saber", -"sabered", -"sabicu", -"sabina", -"sabine", -"sabino", -"sable", -"sably", -"sabora", -"sabot", -"saboted", -"sabra", -"sabulum", -"saburra", -"sabutan", -"sabzi", -"sac", -"sacaton", -"sacatra", -"saccade", -"saccate", -"saccos", -"saccule", -"saccus", -"sachem", -"sachet", -"sack", -"sackage", -"sackbag", -"sackbut", -"sacked", -"sacken", -"sacker", -"sackful", -"sacking", -"sackman", -"saclike", -"saco", -"sacope", -"sacque", -"sacra", -"sacrad", -"sacral", -"sacred", -"sacring", -"sacrist", -"sacro", -"sacrum", -"sad", -"sadden", -"saddik", -"saddish", -"saddle", -"saddled", -"saddler", -"sade", -"sadh", -"sadhe", -"sadhu", -"sadic", -"sadiron", -"sadism", -"sadist", -"sadly", -"sadness", -"sado", -"sadr", -"saecula", -"saeter", -"saeume", -"safari", -"safe", -"safely", -"safen", -"safener", -"safety", -"saffian", -"safflor", -"safflow", -"saffron", -"safrole", -"saft", -"sag", -"saga", -"sagaie", -"sagaman", -"sagathy", -"sage", -"sagely", -"sagene", -"sagger", -"sagging", -"saggon", -"saggy", -"saging", -"sagitta", -"sagless", -"sago", -"sagoin", -"saguaro", -"sagum", -"saguran", -"sagwire", -"sagy", -"sah", -"sahh", -"sahib", -"sahme", -"sahukar", -"sai", -"saic", -"said", -"saiga", -"sail", -"sailage", -"sailed", -"sailer", -"sailing", -"sailor", -"saily", -"saim", -"saimiri", -"saimy", -"sain", -"saint", -"sainted", -"saintly", -"saip", -"sair", -"sairly", -"sairve", -"sairy", -"saithe", -"saj", -"sajou", -"sake", -"sakeber", -"sakeen", -"saker", -"sakeret", -"saki", -"sakieh", -"sakulya", -"sal", -"salaam", -"salable", -"salably", -"salacot", -"salad", -"salago", -"salal", -"salamo", -"salar", -"salary", -"salat", -"salay", -"sale", -"salele", -"salema", -"salep", -"salfern", -"salic", -"salicin", -"salicyl", -"salient", -"salify", -"saligot", -"salina", -"saline", -"salite", -"salited", -"saliva", -"salival", -"salix", -"salle", -"sallee", -"sallet", -"sallier", -"salloo", -"sallow", -"sallowy", -"sally", -"salma", -"salmiac", -"salmine", -"salmis", -"salmon", -"salol", -"salomon", -"salon", -"saloon", -"saloop", -"salp", -"salpa", -"salpian", -"salpinx", -"salpoid", -"salse", -"salsify", -"salt", -"salta", -"saltant", -"saltary", -"saltate", -"saltcat", -"salted", -"saltee", -"salten", -"salter", -"saltern", -"saltery", -"saltfat", -"saltier", -"saltine", -"salting", -"saltish", -"saltly", -"saltman", -"saltpan", -"saltus", -"salty", -"saluki", -"salung", -"salute", -"saluter", -"salvage", -"salve", -"salver", -"salviol", -"salvo", -"salvor", -"salvy", -"sam", -"samadh", -"samadhi", -"samaj", -"saman", -"samara", -"samaria", -"samarra", -"samba", -"sambal", -"sambar", -"sambo", -"sambuk", -"sambuke", -"same", -"samekh", -"samel", -"samely", -"samen", -"samh", -"samhita", -"samiel", -"samiri", -"samisen", -"samite", -"samkara", -"samlet", -"sammel", -"sammer", -"sammier", -"sammy", -"samovar", -"samp", -"sampan", -"sampi", -"sample", -"sampler", -"samsara", -"samshu", -"samson", -"samurai", -"san", -"sanable", -"sanai", -"sancho", -"sanct", -"sancta", -"sanctum", -"sand", -"sandak", -"sandal", -"sandan", -"sandbag", -"sandbin", -"sandbox", -"sandboy", -"sandbur", -"sanded", -"sander", -"sanders", -"sandhi", -"sanding", -"sandix", -"sandman", -"sandust", -"sandy", -"sane", -"sanely", -"sang", -"sanga", -"sangar", -"sangei", -"sanger", -"sangha", -"sangley", -"sangrel", -"sangsue", -"sanicle", -"sanies", -"sanify", -"sanious", -"sanity", -"sanjak", -"sank", -"sankha", -"sannup", -"sans", -"sansei", -"sansi", -"sant", -"santal", -"santene", -"santimi", -"santims", -"santir", -"santon", -"sao", -"sap", -"sapa", -"sapajou", -"sapan", -"sapbush", -"sapek", -"sapful", -"saphead", -"saphena", -"saphie", -"sapid", -"sapient", -"sapin", -"sapinda", -"saple", -"sapless", -"sapling", -"sapo", -"saponin", -"sapor", -"sapota", -"sapote", -"sappare", -"sapper", -"sapphic", -"sapping", -"sapples", -"sappy", -"saprine", -"sapsago", -"sapsuck", -"sapwood", -"sapwort", -"sar", -"saraad", -"saraf", -"sarangi", -"sarcasm", -"sarcast", -"sarcine", -"sarcle", -"sarcler", -"sarcode", -"sarcoid", -"sarcoma", -"sarcous", -"sard", -"sardel", -"sardine", -"sardius", -"sare", -"sargo", -"sargus", -"sari", -"sarif", -"sarigue", -"sarinda", -"sarip", -"sark", -"sarkar", -"sarkful", -"sarkine", -"sarking", -"sarkit", -"sarlak", -"sarlyk", -"sarment", -"sarna", -"sarod", -"saron", -"sarong", -"saronic", -"saros", -"sarpler", -"sarpo", -"sarra", -"sarraf", -"sarsa", -"sarsen", -"sart", -"sartage", -"sartain", -"sartor", -"sarus", -"sarwan", -"sasa", -"sasan", -"sasani", -"sash", -"sashay", -"sashery", -"sashing", -"sasin", -"sasine", -"sassaby", -"sassy", -"sat", -"satable", -"satan", -"satang", -"satanic", -"satara", -"satchel", -"sate", -"sateen", -"satiate", -"satient", -"satiety", -"satin", -"satine", -"satined", -"satiny", -"satire", -"satiric", -"satisfy", -"satlijk", -"satrap", -"satrapy", -"satron", -"sattle", -"sattva", -"satura", -"satyr", -"satyric", -"sauce", -"saucer", -"saucily", -"saucy", -"sauf", -"sauger", -"saugh", -"saughen", -"sauld", -"saulie", -"sault", -"saulter", -"saum", -"saumon", -"saumont", -"sauna", -"saunter", -"sauqui", -"saur", -"saurel", -"saurian", -"saury", -"sausage", -"saut", -"saute", -"sauteur", -"sauty", -"sauve", -"savable", -"savacu", -"savage", -"savanna", -"savant", -"savarin", -"save", -"saved", -"saveloy", -"saver", -"savin", -"saving", -"savior", -"savola", -"savor", -"savored", -"savorer", -"savory", -"savour", -"savoy", -"savoyed", -"savssat", -"savvy", -"saw", -"sawah", -"sawali", -"sawarra", -"sawback", -"sawbill", -"sawbuck", -"sawbwa", -"sawder", -"sawdust", -"sawed", -"sawer", -"sawfish", -"sawfly", -"sawing", -"sawish", -"sawlike", -"sawman", -"sawmill", -"sawmon", -"sawmont", -"sawn", -"sawney", -"sawt", -"sawway", -"sawwort", -"sawyer", -"sax", -"saxhorn", -"saxten", -"saxtie", -"saxtuba", -"say", -"saya", -"sayable", -"sayer", -"sayette", -"sayid", -"saying", -"sazen", -"sblood", -"scab", -"scabbed", -"scabble", -"scabby", -"scabid", -"scabies", -"scabish", -"scabrid", -"scad", -"scaddle", -"scads", -"scaff", -"scaffer", -"scaffie", -"scaffle", -"scaglia", -"scala", -"scalage", -"scalar", -"scalare", -"scald", -"scalded", -"scalder", -"scaldic", -"scaldy", -"scale", -"scaled", -"scalena", -"scalene", -"scaler", -"scales", -"scaling", -"scall", -"scalled", -"scallom", -"scallop", -"scalma", -"scaloni", -"scalp", -"scalpel", -"scalper", -"scalt", -"scaly", -"scam", -"scamble", -"scamell", -"scamler", -"scamles", -"scamp", -"scamper", -"scan", -"scandal", -"scandia", -"scandic", -"scanmag", -"scanner", -"scant", -"scantle", -"scantly", -"scanty", -"scap", -"scape", -"scapel", -"scapha", -"scapoid", -"scapose", -"scapple", -"scapula", -"scapus", -"scar", -"scarab", -"scarce", -"scarcen", -"scare", -"scarer", -"scarf", -"scarfed", -"scarfer", -"scarfy", -"scarid", -"scarify", -"scarily", -"scarlet", -"scarman", -"scarn", -"scaroid", -"scarp", -"scarred", -"scarrer", -"scarry", -"scart", -"scarth", -"scarus", -"scarved", -"scary", -"scase", -"scasely", -"scat", -"scatch", -"scathe", -"scatter", -"scatty", -"scatula", -"scaul", -"scaum", -"scaup", -"scauper", -"scaur", -"scaurie", -"scaut", -"scavage", -"scavel", -"scaw", -"scawd", -"scawl", -"scazon", -"sceat", -"scena", -"scenary", -"scend", -"scene", -"scenery", -"scenic", -"scenist", -"scenite", -"scent", -"scented", -"scenter", -"scepsis", -"scepter", -"sceptic", -"sceptry", -"scerne", -"schanz", -"schappe", -"scharf", -"schelly", -"schema", -"scheme", -"schemer", -"schemy", -"schene", -"schepel", -"schepen", -"scherm", -"scherzi", -"scherzo", -"schesis", -"schism", -"schisma", -"schist", -"schloop", -"schmelz", -"scho", -"schola", -"scholae", -"scholar", -"scholia", -"schone", -"school", -"schoon", -"schorl", -"schorly", -"schout", -"schtoff", -"schuh", -"schuhe", -"schuit", -"schule", -"schuss", -"schute", -"schwa", -"schwarz", -"sciapod", -"sciarid", -"sciatic", -"scibile", -"science", -"scient", -"scincid", -"scind", -"sciniph", -"scintle", -"scion", -"scious", -"scirrhi", -"scissel", -"scissor", -"sciurid", -"sclaff", -"sclate", -"sclater", -"sclaw", -"scler", -"sclera", -"scleral", -"sclere", -"scliff", -"sclim", -"sclimb", -"scoad", -"scob", -"scobby", -"scobs", -"scoff", -"scoffer", -"scog", -"scoggan", -"scogger", -"scoggin", -"scoke", -"scolb", -"scold", -"scolder", -"scolex", -"scolia", -"scoliid", -"scolion", -"scolite", -"scollop", -"scolog", -"sconce", -"sconcer", -"scone", -"scoon", -"scoop", -"scooped", -"scooper", -"scoot", -"scooter", -"scopa", -"scopate", -"scope", -"scopet", -"scopic", -"scopine", -"scopola", -"scops", -"scopula", -"scorch", -"score", -"scored", -"scorer", -"scoria", -"scoriac", -"scoriae", -"scorify", -"scoring", -"scorn", -"scorned", -"scorner", -"scorny", -"scorper", -"scorse", -"scot", -"scotale", -"scotch", -"scote", -"scoter", -"scotia", -"scotino", -"scotoma", -"scotomy", -"scouch", -"scouk", -"scoup", -"scour", -"scoured", -"scourer", -"scourge", -"scoury", -"scouse", -"scout", -"scouter", -"scouth", -"scove", -"scovel", -"scovy", -"scow", -"scowder", -"scowl", -"scowler", -"scowman", -"scrab", -"scrabe", -"scrae", -"scrag", -"scraggy", -"scraily", -"scram", -"scran", -"scranch", -"scrank", -"scranky", -"scranny", -"scrap", -"scrape", -"scraped", -"scraper", -"scrapie", -"scrappy", -"scrapy", -"scrat", -"scratch", -"scrath", -"scrauch", -"scraw", -"scrawk", -"scrawl", -"scrawly", -"scrawm", -"scrawny", -"scray", -"scraze", -"screak", -"screaky", -"scream", -"screamy", -"scree", -"screech", -"screed", -"screek", -"screel", -"screen", -"screeny", -"screet", -"screeve", -"screich", -"screigh", -"screve", -"screver", -"screw", -"screwed", -"screwer", -"screwy", -"scribal", -"scribe", -"scriber", -"scride", -"scrieve", -"scrike", -"scrim", -"scrime", -"scrimer", -"scrimp", -"scrimpy", -"scrin", -"scrinch", -"scrine", -"scringe", -"scrip", -"scripee", -"script", -"scritch", -"scrive", -"scriven", -"scriver", -"scrob", -"scrobe", -"scrobis", -"scrod", -"scroff", -"scrog", -"scroggy", -"scrolar", -"scroll", -"scrolly", -"scroo", -"scrooch", -"scrooge", -"scroop", -"scrota", -"scrotal", -"scrotum", -"scrouge", -"scrout", -"scrow", -"scroyle", -"scrub", -"scrubby", -"scruf", -"scruff", -"scruffy", -"scruft", -"scrum", -"scrump", -"scrunch", -"scrunge", -"scrunt", -"scruple", -"scrush", -"scruto", -"scruze", -"scry", -"scryer", -"scud", -"scudder", -"scuddle", -"scuddy", -"scudi", -"scudler", -"scudo", -"scuff", -"scuffed", -"scuffer", -"scuffle", -"scuffly", -"scuffy", -"scuft", -"scufter", -"scug", -"sculch", -"scull", -"sculler", -"scullog", -"sculp", -"sculper", -"sculpin", -"sculpt", -"sculsh", -"scum", -"scumber", -"scumble", -"scummed", -"scummer", -"scummy", -"scun", -"scunder", -"scunner", -"scup", -"scupful", -"scupper", -"scuppet", -"scur", -"scurdy", -"scurf", -"scurfer", -"scurfy", -"scurry", -"scurvy", -"scuse", -"scut", -"scuta", -"scutage", -"scutal", -"scutate", -"scutch", -"scute", -"scutel", -"scutter", -"scuttle", -"scutty", -"scutula", -"scutum", -"scybala", -"scye", -"scypha", -"scyphae", -"scyphi", -"scyphoi", -"scyphus", -"scyt", -"scytale", -"scythe", -"sdeath", -"se", -"sea", -"seadog", -"seafare", -"seafolk", -"seafowl", -"seagirt", -"seagoer", -"seah", -"seak", -"seal", -"sealant", -"sealch", -"sealed", -"sealer", -"sealery", -"sealess", -"sealet", -"sealike", -"sealine", -"sealing", -"seam", -"seaman", -"seamark", -"seamed", -"seamer", -"seaming", -"seamlet", -"seamost", -"seamrog", -"seamy", -"seance", -"seaport", -"sear", -"searce", -"searcer", -"search", -"seared", -"searer", -"searing", -"seary", -"seasick", -"seaside", -"season", -"seat", -"seatang", -"seated", -"seater", -"seathe", -"seating", -"seatron", -"seave", -"seavy", -"seawant", -"seaward", -"seaware", -"seaway", -"seaweed", -"seawife", -"seaworn", -"seax", -"sebacic", -"sebait", -"sebate", -"sebific", -"sebilla", -"sebkha", -"sebum", -"sebundy", -"sec", -"secable", -"secalin", -"secancy", -"secant", -"secede", -"seceder", -"secern", -"secesh", -"sech", -"seck", -"seclude", -"secluse", -"secohm", -"second", -"seconde", -"secos", -"secpar", -"secque", -"secre", -"secrecy", -"secret", -"secreta", -"secrete", -"secreto", -"sect", -"sectary", -"sectile", -"section", -"sectism", -"sectist", -"sective", -"sector", -"secular", -"secund", -"secure", -"securer", -"sedan", -"sedate", -"sedent", -"sedge", -"sedged", -"sedging", -"sedgy", -"sedile", -"sedilia", -"seduce", -"seducee", -"seducer", -"seduct", -"sedum", -"see", -"seeable", -"seech", -"seed", -"seedage", -"seedbed", -"seedbox", -"seeded", -"seeder", -"seedful", -"seedily", -"seedkin", -"seedlet", -"seedlip", -"seedman", -"seedy", -"seege", -"seeing", -"seek", -"seeker", -"seeking", -"seel", -"seelful", -"seely", -"seem", -"seemer", -"seeming", -"seemly", -"seen", -"seenie", -"seep", -"seepage", -"seeped", -"seepy", -"seer", -"seeress", -"seerpaw", -"seesaw", -"seesee", -"seethe", -"seg", -"seggar", -"seggard", -"segged", -"seggrom", -"segment", -"sego", -"segol", -"seiche", -"seidel", -"seine", -"seiner", -"seise", -"seism", -"seismal", -"seismic", -"seit", -"seity", -"seize", -"seizer", -"seizin", -"seizing", -"seizor", -"seizure", -"sejant", -"sejoin", -"sejunct", -"sekos", -"selah", -"selamin", -"seldom", -"seldor", -"sele", -"select", -"selenic", -"self", -"selfdom", -"selfful", -"selfish", -"selfism", -"selfist", -"selfly", -"selion", -"sell", -"sella", -"sellar", -"sellate", -"seller", -"sellie", -"selling", -"sellout", -"selly", -"selsyn", -"selt", -"selva", -"selvage", -"semarum", -"sematic", -"semball", -"semble", -"seme", -"semeed", -"semeia", -"semeion", -"semen", -"semence", -"semese", -"semi", -"semiape", -"semiarc", -"semibay", -"semic", -"semicup", -"semidry", -"semiegg", -"semifib", -"semifit", -"semify", -"semigod", -"semihot", -"seminal", -"seminar", -"semiorb", -"semiped", -"semipro", -"semiraw", -"semis", -"semita", -"semitae", -"semital", -"semiurn", -"semmet", -"semmit", -"semola", -"semsem", -"sen", -"senaite", -"senam", -"senary", -"senate", -"senator", -"sence", -"sencion", -"send", -"sendal", -"sendee", -"sender", -"sending", -"senega", -"senegin", -"senesce", -"senile", -"senior", -"senna", -"sennet", -"sennit", -"sennite", -"sensa", -"sensal", -"sensate", -"sense", -"sensed", -"sensify", -"sensile", -"sension", -"sensism", -"sensist", -"sensive", -"sensize", -"senso", -"sensor", -"sensory", -"sensual", -"sensum", -"sensyne", -"sent", -"sentry", -"sepad", -"sepal", -"sepaled", -"sephen", -"sepia", -"sepian", -"sepiary", -"sepic", -"sepioid", -"sepion", -"sepiost", -"sepium", -"sepone", -"sepoy", -"seppuku", -"seps", -"sepsine", -"sepsis", -"sept", -"septa", -"septal", -"septan", -"septane", -"septate", -"septave", -"septet", -"septic", -"septier", -"septile", -"septime", -"septoic", -"septole", -"septum", -"septuor", -"sequa", -"sequel", -"sequela", -"sequent", -"sequest", -"sequin", -"ser", -"sera", -"serab", -"seragli", -"serai", -"serail", -"seral", -"serang", -"serape", -"seraph", -"serau", -"seraw", -"sercial", -"serdab", -"sere", -"sereh", -"serene", -"serf", -"serfage", -"serfdom", -"serfish", -"serfism", -"serge", -"serger", -"serging", -"serial", -"seriary", -"seriate", -"sericea", -"sericin", -"seriema", -"series", -"serif", -"serific", -"serin", -"serine", -"seringa", -"serio", -"serious", -"serment", -"sermo", -"sermon", -"sero", -"serolin", -"seron", -"seroon", -"seroot", -"seropus", -"serosa", -"serous", -"serow", -"serpent", -"serphid", -"serpigo", -"serpula", -"serra", -"serrage", -"serran", -"serrana", -"serrano", -"serrate", -"serried", -"serry", -"sert", -"serta", -"sertule", -"sertum", -"serum", -"serumal", -"serut", -"servage", -"serval", -"servant", -"serve", -"server", -"servery", -"servet", -"service", -"servile", -"serving", -"servist", -"servo", -"sesame", -"sesma", -"sesqui", -"sess", -"sessile", -"session", -"sestet", -"sesti", -"sestiad", -"sestina", -"sestine", -"sestole", -"sestuor", -"set", -"seta", -"setae", -"setal", -"setback", -"setbolt", -"setdown", -"setfast", -"seth", -"sethead", -"setier", -"setline", -"setness", -"setoff", -"seton", -"setose", -"setous", -"setout", -"setover", -"setsman", -"sett", -"settee", -"setter", -"setting", -"settle", -"settled", -"settler", -"settlor", -"setula", -"setule", -"setup", -"setwall", -"setwise", -"setwork", -"seugh", -"seven", -"sevener", -"seventh", -"seventy", -"sever", -"several", -"severe", -"severer", -"severy", -"sew", -"sewable", -"sewage", -"sewan", -"sewed", -"sewen", -"sewer", -"sewered", -"sewery", -"sewing", -"sewless", -"sewn", -"sex", -"sexed", -"sexern", -"sexfid", -"sexfoil", -"sexhood", -"sexifid", -"sexiped", -"sexless", -"sexlike", -"sexly", -"sext", -"sextain", -"sextan", -"sextans", -"sextant", -"sextar", -"sextary", -"sextern", -"sextet", -"sextic", -"sextile", -"sexto", -"sextole", -"sexton", -"sextry", -"sextula", -"sexual", -"sexuale", -"sexuous", -"sexy", -"sey", -"sfoot", -"sh", -"sha", -"shab", -"shabash", -"shabbed", -"shabble", -"shabby", -"shachle", -"shachly", -"shack", -"shackle", -"shackly", -"shacky", -"shad", -"shade", -"shaded", -"shader", -"shadily", -"shadine", -"shading", -"shadkan", -"shadoof", -"shadow", -"shadowy", -"shady", -"shaffle", -"shaft", -"shafted", -"shafter", -"shafty", -"shag", -"shagbag", -"shagged", -"shaggy", -"shaglet", -"shagrag", -"shah", -"shahdom", -"shahi", -"shahin", -"shaikh", -"shaitan", -"shake", -"shaken", -"shaker", -"shakers", -"shakha", -"shakily", -"shaking", -"shako", -"shakti", -"shaku", -"shaky", -"shale", -"shall", -"shallal", -"shallon", -"shallop", -"shallot", -"shallow", -"shallu", -"shalom", -"shalt", -"shalwar", -"shaly", -"sham", -"shama", -"shamal", -"shamalo", -"shaman", -"shamba", -"shamble", -"shame", -"shamed", -"shamer", -"shamir", -"shammed", -"shammer", -"shammy", -"shampoo", -"shan", -"shandry", -"shandy", -"shangan", -"shank", -"shanked", -"shanker", -"shanna", -"shanny", -"shansa", -"shant", -"shanty", -"shap", -"shape", -"shaped", -"shapely", -"shapen", -"shaper", -"shaping", -"shaps", -"shapy", -"shard", -"sharded", -"shardy", -"share", -"sharer", -"shargar", -"shark", -"sharky", -"sharn", -"sharny", -"sharp", -"sharpen", -"sharper", -"sharpie", -"sharply", -"sharps", -"sharpy", -"sharrag", -"sharry", -"shaster", -"shastra", -"shastri", -"shat", -"shatan", -"shatter", -"shaugh", -"shaul", -"shaup", -"shauri", -"shauwe", -"shave", -"shaved", -"shavee", -"shaven", -"shaver", -"shavery", -"shaving", -"shaw", -"shawl", -"shawled", -"shawm", -"shawny", -"shawy", -"shay", -"she", -"shea", -"sheaf", -"sheafy", -"sheal", -"shear", -"sheard", -"shearer", -"shears", -"sheat", -"sheath", -"sheathe", -"sheathy", -"sheave", -"sheaved", -"shebang", -"shebeen", -"shed", -"shedded", -"shedder", -"sheder", -"shedman", -"shee", -"sheely", -"sheen", -"sheenly", -"sheeny", -"sheep", -"sheepy", -"sheer", -"sheered", -"sheerly", -"sheet", -"sheeted", -"sheeter", -"sheety", -"sheik", -"sheikly", -"shekel", -"shela", -"sheld", -"shelder", -"shelf", -"shelfy", -"shell", -"shellac", -"shelled", -"sheller", -"shellum", -"shelly", -"shelta", -"shelter", -"shelty", -"shelve", -"shelver", -"shelvy", -"shend", -"sheng", -"sheolic", -"sheppey", -"sher", -"sherbet", -"sheriat", -"sherif", -"sherifa", -"sheriff", -"sherifi", -"sherify", -"sherry", -"sheth", -"sheugh", -"sheva", -"shevel", -"shevri", -"shewa", -"shewel", -"sheyle", -"shi", -"shibah", -"shibar", -"shice", -"shicer", -"shicker", -"shide", -"shied", -"shiel", -"shield", -"shier", -"shies", -"shiest", -"shift", -"shifter", -"shifty", -"shigram", -"shih", -"shikar", -"shikara", -"shikari", -"shikimi", -"shikken", -"shiko", -"shikra", -"shilf", -"shilfa", -"shill", -"shilla", -"shillet", -"shilloo", -"shilpit", -"shim", -"shimal", -"shimmer", -"shimmy", -"shimose", -"shimper", -"shin", -"shindig", -"shindle", -"shindy", -"shine", -"shiner", -"shingle", -"shingly", -"shinily", -"shining", -"shinner", -"shinny", -"shinty", -"shiny", -"shinza", -"ship", -"shipboy", -"shipful", -"shiplap", -"shiplet", -"shipman", -"shipped", -"shipper", -"shippo", -"shippon", -"shippy", -"shipway", -"shire", -"shirk", -"shirker", -"shirky", -"shirl", -"shirpit", -"shirr", -"shirt", -"shirty", -"shish", -"shisham", -"shisn", -"shita", -"shither", -"shittah", -"shittim", -"shiv", -"shive", -"shiver", -"shivery", -"shivey", -"shivoo", -"shivy", -"sho", -"shoad", -"shoader", -"shoal", -"shoaler", -"shoaly", -"shoat", -"shock", -"shocker", -"shod", -"shodden", -"shoddy", -"shode", -"shoder", -"shoe", -"shoeboy", -"shoeing", -"shoeman", -"shoer", -"shoful", -"shog", -"shogaol", -"shoggie", -"shoggle", -"shoggly", -"shogi", -"shogun", -"shohet", -"shoji", -"shola", -"shole", -"shone", -"shoneen", -"shoo", -"shood", -"shoofa", -"shoofly", -"shooi", -"shook", -"shool", -"shooler", -"shoop", -"shoor", -"shoot", -"shootee", -"shooter", -"shop", -"shopboy", -"shopful", -"shophar", -"shoplet", -"shopman", -"shoppe", -"shopper", -"shoppy", -"shoq", -"shor", -"shoran", -"shore", -"shored", -"shorer", -"shoring", -"shorn", -"short", -"shorten", -"shorter", -"shortly", -"shorts", -"shot", -"shote", -"shotgun", -"shotman", -"shott", -"shotted", -"shotten", -"shotter", -"shotty", -"shou", -"should", -"shout", -"shouter", -"shoval", -"shove", -"shovel", -"shover", -"show", -"showdom", -"shower", -"showery", -"showily", -"showing", -"showish", -"showman", -"shown", -"showup", -"showy", -"shoya", -"shrab", -"shradh", -"shraf", -"shrag", -"shram", -"shrank", -"shrap", -"shrave", -"shravey", -"shred", -"shreddy", -"shree", -"shreeve", -"shrend", -"shrew", -"shrewd", -"shrewdy", -"shrewly", -"shriek", -"shrieky", -"shrift", -"shrike", -"shrill", -"shrilly", -"shrimp", -"shrimpi", -"shrimpy", -"shrinal", -"shrine", -"shrink", -"shrinky", -"shrip", -"shrite", -"shrive", -"shrivel", -"shriven", -"shriver", -"shroff", -"shrog", -"shroud", -"shroudy", -"shrove", -"shrover", -"shrub", -"shrubby", -"shruff", -"shrug", -"shrunk", -"shrups", -"shuba", -"shuck", -"shucker", -"shucks", -"shudder", -"shuff", -"shuffle", -"shug", -"shul", -"shuler", -"shumac", -"shun", -"shune", -"shunner", -"shunt", -"shunter", -"shure", -"shurf", -"shush", -"shusher", -"shut", -"shutoff", -"shutout", -"shutten", -"shutter", -"shuttle", -"shy", -"shyer", -"shyish", -"shyly", -"shyness", -"shyster", -"si", -"siak", -"sial", -"sialic", -"sialid", -"sialoid", -"siamang", -"sib", -"sibbed", -"sibbens", -"sibber", -"sibby", -"sibilus", -"sibling", -"sibness", -"sibrede", -"sibship", -"sibyl", -"sibylic", -"sibylla", -"sic", -"sicca", -"siccant", -"siccate", -"siccity", -"sice", -"sick", -"sickbed", -"sicken", -"sicker", -"sickish", -"sickle", -"sickled", -"sickler", -"sickly", -"sicsac", -"sicula", -"sicular", -"sidder", -"siddur", -"side", -"sideage", -"sidearm", -"sidecar", -"sided", -"sider", -"sideral", -"siderin", -"sides", -"sideway", -"sidhe", -"sidi", -"siding", -"sidle", -"sidler", -"sidling", -"sidth", -"sidy", -"sie", -"siege", -"sieger", -"sienna", -"sier", -"siering", -"sierra", -"sierran", -"siesta", -"sieve", -"siever", -"sievy", -"sifac", -"sifaka", -"sife", -"siffle", -"sifflet", -"sifflot", -"sift", -"siftage", -"sifted", -"sifter", -"sifting", -"sig", -"sigger", -"sigh", -"sigher", -"sighful", -"sighing", -"sight", -"sighted", -"sighten", -"sighter", -"sightly", -"sighty", -"sigil", -"sigla", -"siglos", -"sigma", -"sigmate", -"sigmoid", -"sign", -"signal", -"signary", -"signate", -"signee", -"signer", -"signet", -"signify", -"signior", -"signist", -"signman", -"signory", -"signum", -"sika", -"sikar", -"sikatch", -"sike", -"sikerly", -"siket", -"sikhara", -"sikhra", -"sil", -"silage", -"silane", -"sile", -"silen", -"silence", -"silency", -"sileni", -"silenic", -"silent", -"silenus", -"silesia", -"silex", -"silica", -"silicam", -"silicic", -"silicle", -"silico", -"silicon", -"silicyl", -"siliqua", -"silique", -"silk", -"silked", -"silken", -"silker", -"silkie", -"silkily", -"silkman", -"silky", -"sill", -"sillar", -"siller", -"sillily", -"sillock", -"sillon", -"silly", -"silo", -"siloist", -"silphid", -"silt", -"siltage", -"silting", -"silty", -"silurid", -"silva", -"silvan", -"silver", -"silvern", -"silvery", -"silvics", -"silyl", -"sima", -"simal", -"simar", -"simball", -"simbil", -"simblin", -"simblot", -"sime", -"simiad", -"simial", -"simian", -"similar", -"simile", -"similor", -"simioid", -"simious", -"simity", -"simkin", -"simlin", -"simling", -"simmer", -"simmon", -"simnel", -"simony", -"simool", -"simoom", -"simoon", -"simous", -"simp", -"simpai", -"simper", -"simple", -"simpler", -"simplex", -"simply", -"simsim", -"simson", -"simular", -"simuler", -"sin", -"sina", -"sinaite", -"sinal", -"sinamay", -"sinapic", -"sinapis", -"sinawa", -"since", -"sincere", -"sind", -"sinder", -"sindle", -"sindoc", -"sindon", -"sindry", -"sine", -"sinew", -"sinewed", -"sinewy", -"sinful", -"sing", -"singe", -"singed", -"singer", -"singey", -"singh", -"singing", -"single", -"singled", -"singler", -"singles", -"singlet", -"singly", -"singult", -"sinh", -"sink", -"sinkage", -"sinker", -"sinking", -"sinky", -"sinless", -"sinlike", -"sinnen", -"sinner", -"sinnet", -"sinopia", -"sinople", -"sinsion", -"sinsyne", -"sinter", -"sintoc", -"sinuate", -"sinuose", -"sinuous", -"sinus", -"sinusal", -"sinward", -"siol", -"sion", -"sip", -"sipage", -"sipe", -"siper", -"siphoid", -"siphon", -"sipid", -"siping", -"sipling", -"sipper", -"sippet", -"sippio", -"sir", -"sircar", -"sirdar", -"sire", -"siren", -"sirene", -"sirenic", -"sireny", -"siress", -"sirgang", -"sirian", -"siricid", -"sirih", -"siris", -"sirkeer", -"sirki", -"sirky", -"sirloin", -"siroc", -"sirocco", -"sirpea", -"sirple", -"sirpoon", -"sirrah", -"sirree", -"sirship", -"sirup", -"siruped", -"siruper", -"sirupy", -"sis", -"sisal", -"sise", -"sisel", -"sish", -"sisham", -"sisi", -"siskin", -"siss", -"sissify", -"sissoo", -"sissy", -"sist", -"sister", -"sistern", -"sistle", -"sistrum", -"sit", -"sitao", -"sitar", -"sitch", -"site", -"sitfast", -"sith", -"sithe", -"sithens", -"sitient", -"sitio", -"sittee", -"sitten", -"sitter", -"sittine", -"sitting", -"situal", -"situate", -"situla", -"situlae", -"situs", -"siva", -"siver", -"sivvens", -"siwash", -"six", -"sixain", -"sixer", -"sixfoil", -"sixfold", -"sixsome", -"sixte", -"sixteen", -"sixth", -"sixthet", -"sixthly", -"sixty", -"sizable", -"sizably", -"sizal", -"sizar", -"size", -"sized", -"sizeman", -"sizer", -"sizes", -"sizing", -"sizy", -"sizygia", -"sizz", -"sizzard", -"sizzing", -"sizzle", -"sjambok", -"skaddle", -"skaff", -"skaffie", -"skag", -"skair", -"skal", -"skance", -"skart", -"skasely", -"skat", -"skate", -"skater", -"skatiku", -"skating", -"skatist", -"skatole", -"skaw", -"skean", -"skedge", -"skee", -"skeed", -"skeeg", -"skeel", -"skeely", -"skeen", -"skeer", -"skeered", -"skeery", -"skeet", -"skeeter", -"skeezix", -"skeg", -"skegger", -"skeif", -"skeigh", -"skeily", -"skein", -"skeiner", -"skeipp", -"skel", -"skelder", -"skelf", -"skelic", -"skell", -"skellat", -"skeller", -"skellum", -"skelly", -"skelp", -"skelper", -"skelpin", -"skelter", -"skemmel", -"skemp", -"sken", -"skene", -"skeo", -"skeough", -"skep", -"skepful", -"skeptic", -"sker", -"skere", -"skerret", -"skerry", -"sketch", -"sketchy", -"skete", -"skevish", -"skew", -"skewed", -"skewer", -"skewl", -"skewly", -"skewy", -"skey", -"ski", -"skiapod", -"skibby", -"skice", -"skid", -"skidded", -"skidder", -"skiddoo", -"skiddy", -"skidpan", -"skidway", -"skied", -"skieppe", -"skier", -"skies", -"skiff", -"skift", -"skiing", -"skijore", -"skil", -"skilder", -"skill", -"skilled", -"skillet", -"skilly", -"skilpot", -"skilts", -"skim", -"skime", -"skimmed", -"skimmer", -"skimp", -"skimpy", -"skin", -"skinch", -"skinful", -"skink", -"skinker", -"skinkle", -"skinned", -"skinner", -"skinny", -"skip", -"skipman", -"skippel", -"skipper", -"skippet", -"skipple", -"skippy", -"skirl", -"skirp", -"skirr", -"skirreh", -"skirret", -"skirt", -"skirted", -"skirter", -"skirty", -"skit", -"skite", -"skiter", -"skither", -"skitter", -"skittle", -"skitty", -"skiv", -"skive", -"skiver", -"skiving", -"sklate", -"sklater", -"sklent", -"skoal", -"skoo", -"skookum", -"skoptsy", -"skout", -"skraigh", -"skrike", -"skrupul", -"skua", -"skulk", -"skulker", -"skull", -"skulled", -"skully", -"skulp", -"skun", -"skunk", -"skunky", -"skuse", -"sky", -"skybal", -"skyey", -"skyful", -"skyish", -"skylark", -"skyless", -"skylike", -"skylook", -"skyman", -"skyphoi", -"skyphos", -"skyre", -"skysail", -"skyugle", -"skyward", -"skyway", -"sla", -"slab", -"slabbed", -"slabber", -"slabby", -"slabman", -"slack", -"slacked", -"slacken", -"slacker", -"slackly", -"slad", -"sladang", -"slade", -"slae", -"slag", -"slagger", -"slaggy", -"slagman", -"slain", -"slainte", -"slait", -"slake", -"slaker", -"slaking", -"slaky", -"slam", -"slamp", -"slander", -"slane", -"slang", -"slangy", -"slank", -"slant", -"slantly", -"slap", -"slape", -"slapper", -"slare", -"slart", -"slarth", -"slash", -"slashed", -"slasher", -"slashy", -"slat", -"slatch", -"slate", -"slater", -"slath", -"slather", -"slatify", -"slating", -"slatish", -"slatted", -"slatter", -"slaty", -"slaum", -"slave", -"slaved", -"slaver", -"slavery", -"slavey", -"slaving", -"slavish", -"slaw", -"slay", -"slayer", -"slaying", -"sleathy", -"sleave", -"sleaved", -"sleazy", -"sleck", -"sled", -"sledded", -"sledder", -"sledful", -"sledge", -"sledger", -"slee", -"sleech", -"sleechy", -"sleek", -"sleeken", -"sleeker", -"sleekit", -"sleekly", -"sleeky", -"sleep", -"sleeper", -"sleepry", -"sleepy", -"sleer", -"sleet", -"sleety", -"sleeve", -"sleeved", -"sleever", -"sleigh", -"sleight", -"slender", -"slent", -"slepez", -"slept", -"slete", -"sleuth", -"slew", -"slewed", -"slewer", -"slewing", -"sley", -"sleyer", -"slice", -"sliced", -"slicer", -"slich", -"slicht", -"slicing", -"slick", -"slicken", -"slicker", -"slickly", -"slid", -"slidage", -"slidden", -"slidder", -"slide", -"slided", -"slider", -"sliding", -"slifter", -"slight", -"slighty", -"slim", -"slime", -"slimer", -"slimily", -"slimish", -"slimly", -"slimpsy", -"slimsy", -"slimy", -"sline", -"sling", -"slinge", -"slinger", -"slink", -"slinker", -"slinky", -"slip", -"slipe", -"slipman", -"slipped", -"slipper", -"slippy", -"slipway", -"slirt", -"slish", -"slit", -"slitch", -"slite", -"slither", -"slithy", -"slitted", -"slitter", -"slitty", -"slive", -"sliver", -"slivery", -"sliving", -"sloan", -"slob", -"slobber", -"slobby", -"slock", -"slocken", -"slod", -"slodder", -"slodge", -"slodger", -"sloe", -"slog", -"slogan", -"slogger", -"sloka", -"sloke", -"slon", -"slone", -"slonk", -"sloo", -"sloom", -"sloomy", -"sloop", -"sloosh", -"slop", -"slope", -"sloped", -"slopely", -"sloper", -"sloping", -"slopped", -"sloppy", -"slops", -"slopy", -"slorp", -"slosh", -"slosher", -"sloshy", -"slot", -"slote", -"sloted", -"sloth", -"slotted", -"slotter", -"slouch", -"slouchy", -"slough", -"sloughy", -"slour", -"sloush", -"sloven", -"slow", -"slowish", -"slowly", -"slowrie", -"slows", -"sloyd", -"slub", -"slubber", -"slubby", -"slud", -"sludder", -"sludge", -"sludged", -"sludger", -"sludgy", -"slue", -"sluer", -"slug", -"slugged", -"slugger", -"sluggy", -"sluice", -"sluicer", -"sluicy", -"sluig", -"sluit", -"slum", -"slumber", -"slumdom", -"slumgum", -"slummer", -"slummy", -"slump", -"slumpy", -"slung", -"slunge", -"slunk", -"slunken", -"slur", -"slurbow", -"slurp", -"slurry", -"slush", -"slusher", -"slushy", -"slut", -"slutch", -"slutchy", -"sluther", -"slutter", -"slutty", -"sly", -"slyish", -"slyly", -"slyness", -"slype", -"sma", -"smack", -"smackee", -"smacker", -"smaik", -"small", -"smallen", -"smaller", -"smalls", -"smally", -"smalm", -"smalt", -"smalter", -"smalts", -"smaragd", -"smarm", -"smarmy", -"smart", -"smarten", -"smartly", -"smarty", -"smash", -"smasher", -"smashup", -"smatter", -"smaze", -"smear", -"smeared", -"smearer", -"smeary", -"smectic", -"smectis", -"smeddum", -"smee", -"smeech", -"smeek", -"smeeky", -"smeer", -"smeeth", -"smegma", -"smell", -"smelled", -"smeller", -"smelly", -"smelt", -"smelter", -"smeth", -"smethe", -"smeuse", -"smew", -"smich", -"smicker", -"smicket", -"smiddie", -"smiddum", -"smidge", -"smidgen", -"smilax", -"smile", -"smiler", -"smilet", -"smiling", -"smily", -"smirch", -"smirchy", -"smiris", -"smirk", -"smirker", -"smirkle", -"smirkly", -"smirky", -"smirtle", -"smit", -"smitch", -"smite", -"smiter", -"smith", -"smitham", -"smither", -"smithy", -"smiting", -"smitten", -"smock", -"smocker", -"smog", -"smoke", -"smoked", -"smoker", -"smokery", -"smokily", -"smoking", -"smokish", -"smoky", -"smolder", -"smolt", -"smooch", -"smoochy", -"smoodge", -"smook", -"smoot", -"smooth", -"smopple", -"smore", -"smote", -"smother", -"smotter", -"smouch", -"smous", -"smouse", -"smouser", -"smout", -"smriti", -"smudge", -"smudged", -"smudger", -"smudgy", -"smug", -"smuggle", -"smugism", -"smugly", -"smuisty", -"smur", -"smurr", -"smurry", -"smuse", -"smush", -"smut", -"smutch", -"smutchy", -"smutted", -"smutter", -"smutty", -"smyth", -"smytrie", -"snab", -"snabbie", -"snabble", -"snack", -"snackle", -"snaff", -"snaffle", -"snafu", -"snag", -"snagged", -"snagger", -"snaggy", -"snagrel", -"snail", -"snails", -"snaily", -"snaith", -"snake", -"snaker", -"snakery", -"snakily", -"snaking", -"snakish", -"snaky", -"snap", -"snapbag", -"snape", -"snaper", -"snapped", -"snapper", -"snapps", -"snappy", -"snaps", -"snapy", -"snare", -"snarer", -"snark", -"snarl", -"snarler", -"snarly", -"snary", -"snaste", -"snatch", -"snatchy", -"snath", -"snathe", -"snavel", -"snavvle", -"snaw", -"snead", -"sneak", -"sneaker", -"sneaky", -"sneap", -"sneath", -"sneathe", -"sneb", -"sneck", -"snecker", -"snecket", -"sned", -"snee", -"sneer", -"sneerer", -"sneery", -"sneesh", -"sneest", -"sneesty", -"sneeze", -"sneezer", -"sneezy", -"snell", -"snelly", -"snerp", -"snew", -"snib", -"snibble", -"snibel", -"snicher", -"snick", -"snicker", -"snicket", -"snickey", -"snickle", -"sniddle", -"snide", -"sniff", -"sniffer", -"sniffle", -"sniffly", -"sniffy", -"snift", -"snifter", -"snifty", -"snig", -"snigger", -"sniggle", -"snip", -"snipe", -"sniper", -"sniping", -"snipish", -"snipper", -"snippet", -"snippy", -"snipy", -"snirl", -"snirt", -"snirtle", -"snitch", -"snite", -"snithe", -"snithy", -"snittle", -"snivel", -"snively", -"snivy", -"snob", -"snobber", -"snobby", -"snobdom", -"snocher", -"snock", -"snocker", -"snod", -"snodly", -"snoek", -"snog", -"snoga", -"snoke", -"snood", -"snooded", -"snook", -"snooker", -"snoop", -"snooper", -"snoopy", -"snoose", -"snoot", -"snooty", -"snoove", -"snooze", -"snoozer", -"snoozle", -"snoozy", -"snop", -"snore", -"snorer", -"snoring", -"snork", -"snorkel", -"snorker", -"snort", -"snorter", -"snortle", -"snorty", -"snot", -"snotter", -"snotty", -"snouch", -"snout", -"snouted", -"snouter", -"snouty", -"snow", -"snowcap", -"snowie", -"snowily", -"snowish", -"snowk", -"snowl", -"snowy", -"snozzle", -"snub", -"snubbed", -"snubbee", -"snubber", -"snubby", -"snuck", -"snudge", -"snuff", -"snuffer", -"snuffle", -"snuffly", -"snuffy", -"snug", -"snugger", -"snuggle", -"snugify", -"snugly", -"snum", -"snup", -"snupper", -"snur", -"snurl", -"snurly", -"snurp", -"snurt", -"snuzzle", -"sny", -"snying", -"so", -"soak", -"soakage", -"soaked", -"soaken", -"soaker", -"soaking", -"soakman", -"soaky", -"soally", -"soam", -"soap", -"soapbox", -"soaper", -"soapery", -"soapily", -"soapsud", -"soapy", -"soar", -"soarer", -"soaring", -"soary", -"sob", -"sobber", -"sobbing", -"sobby", -"sobeit", -"sober", -"soberer", -"soberly", -"sobful", -"soboles", -"soc", -"socage", -"socager", -"soccer", -"soce", -"socht", -"social", -"society", -"socii", -"socius", -"sock", -"socker", -"socket", -"sockeye", -"socky", -"socle", -"socman", -"soco", -"sod", -"soda", -"sodaic", -"sodded", -"sodden", -"sodding", -"soddite", -"soddy", -"sodic", -"sodio", -"sodium", -"sodless", -"sodoku", -"sodomic", -"sodomy", -"sodwork", -"sody", -"soe", -"soekoe", -"soever", -"sofa", -"sofane", -"sofar", -"soffit", -"soft", -"softa", -"soften", -"softish", -"softly", -"softner", -"softy", -"sog", -"soger", -"soget", -"soggily", -"sogging", -"soggy", -"soh", -"soho", -"soil", -"soilage", -"soiled", -"soiling", -"soilure", -"soily", -"soiree", -"soja", -"sojourn", -"sok", -"soka", -"soke", -"sokeman", -"soken", -"sol", -"sola", -"solace", -"solacer", -"solan", -"solanal", -"solanum", -"solar", -"solate", -"solatia", -"solay", -"sold", -"soldado", -"soldan", -"solder", -"soldi", -"soldier", -"soldo", -"sole", -"solea", -"soleas", -"soleil", -"solely", -"solemn", -"solen", -"solent", -"soler", -"soles", -"soleus", -"soleyn", -"soli", -"solicit", -"solid", -"solidi", -"solidly", -"solidum", -"solidus", -"solio", -"soliped", -"solist", -"sollar", -"solo", -"solod", -"solodi", -"soloist", -"solon", -"soloth", -"soluble", -"solubly", -"solum", -"solute", -"solvate", -"solve", -"solvend", -"solvent", -"solver", -"soma", -"somal", -"somata", -"somatic", -"somber", -"sombre", -"some", -"someday", -"somehow", -"someone", -"somers", -"someway", -"somewhy", -"somital", -"somite", -"somitic", -"somma", -"somnial", -"somnify", -"somnus", -"sompay", -"sompne", -"sompner", -"son", -"sonable", -"sonance", -"sonancy", -"sonant", -"sonar", -"sonata", -"sond", -"sondeli", -"soneri", -"song", -"songful", -"songish", -"songle", -"songlet", -"songman", -"songy", -"sonhood", -"sonic", -"soniou", -"sonk", -"sonless", -"sonlike", -"sonly", -"sonnet", -"sonny", -"sonoric", -"sons", -"sonship", -"sonsy", -"sontag", -"soodle", -"soodly", -"sook", -"sooky", -"sool", -"sooloos", -"soon", -"sooner", -"soonish", -"soonly", -"soorawn", -"soord", -"soorkee", -"soot", -"sooter", -"sooth", -"soothe", -"soother", -"sootily", -"sooty", -"sop", -"sope", -"soph", -"sophia", -"sophic", -"sophism", -"sophy", -"sopite", -"sopor", -"sopper", -"sopping", -"soppy", -"soprani", -"soprano", -"sora", -"sorage", -"soral", -"sorb", -"sorbate", -"sorbent", -"sorbic", -"sorbile", -"sorbin", -"sorbite", -"sorbose", -"sorbus", -"sorcer", -"sorcery", -"sorchin", -"sorda", -"sordes", -"sordid", -"sordine", -"sordino", -"sordor", -"sore", -"soredia", -"soree", -"sorehon", -"sorely", -"sorema", -"sorgho", -"sorghum", -"sorgo", -"sori", -"soricid", -"sorite", -"sorites", -"sorn", -"sornare", -"sornari", -"sorner", -"sorning", -"soroban", -"sororal", -"sorose", -"sorosis", -"sorra", -"sorrel", -"sorrily", -"sorroa", -"sorrow", -"sorrowy", -"sorry", -"sort", -"sortal", -"sorted", -"sorter", -"sortie", -"sortly", -"sorty", -"sorus", -"sorva", -"sory", -"sosh", -"soshed", -"soso", -"sosoish", -"soss", -"sossle", -"sot", -"sotie", -"sotnia", -"sotnik", -"sotol", -"sots", -"sottage", -"sotted", -"sotter", -"sottish", -"sou", -"souari", -"soubise", -"soucar", -"souchet", -"souchy", -"soud", -"souffle", -"sough", -"sougher", -"sought", -"soul", -"soulack", -"souled", -"soulful", -"soulish", -"souly", -"soum", -"sound", -"sounder", -"soundly", -"soup", -"soupcon", -"souper", -"souple", -"soupy", -"sour", -"source", -"soured", -"souren", -"sourer", -"souring", -"sourish", -"sourly", -"sourock", -"soursop", -"sourtop", -"soury", -"souse", -"souser", -"souslik", -"soutane", -"souter", -"south", -"souther", -"sov", -"soviet", -"sovite", -"sovkhoz", -"sovran", -"sow", -"sowable", -"sowan", -"sowans", -"sowar", -"sowarry", -"sowback", -"sowbane", -"sowel", -"sowens", -"sower", -"sowfoot", -"sowing", -"sowins", -"sowl", -"sowle", -"sowlike", -"sowlth", -"sown", -"sowse", -"sowt", -"sowte", -"soy", -"soya", -"soybean", -"sozin", -"sozolic", -"sozzle", -"sozzly", -"spa", -"space", -"spaced", -"spacer", -"spacing", -"spack", -"spacy", -"spad", -"spade", -"spaded", -"spader", -"spadger", -"spading", -"spadix", -"spadone", -"spae", -"spaedom", -"spaeman", -"spaer", -"spahi", -"spaid", -"spaik", -"spairge", -"spak", -"spald", -"spalder", -"spale", -"spall", -"spaller", -"spalt", -"span", -"spancel", -"spandle", -"spandy", -"spane", -"spanemy", -"spang", -"spangle", -"spangly", -"spaniel", -"spaning", -"spank", -"spanker", -"spanky", -"spann", -"spannel", -"spanner", -"spanule", -"spar", -"sparada", -"sparch", -"spare", -"sparely", -"sparer", -"sparge", -"sparger", -"sparid", -"sparing", -"spark", -"sparked", -"sparker", -"sparkle", -"sparkly", -"sparks", -"sparky", -"sparm", -"sparoid", -"sparred", -"sparrer", -"sparrow", -"sparry", -"sparse", -"spart", -"sparth", -"spartle", -"sparver", -"spary", -"spasm", -"spasmed", -"spasmic", -"spastic", -"spat", -"spate", -"spatha", -"spathal", -"spathe", -"spathed", -"spathic", -"spatial", -"spatted", -"spatter", -"spattle", -"spatula", -"spatule", -"spave", -"spaver", -"spavie", -"spavied", -"spaviet", -"spavin", -"spawn", -"spawner", -"spawny", -"spay", -"spayad", -"spayard", -"spaying", -"speak", -"speaker", -"speal", -"spean", -"spear", -"spearer", -"speary", -"spec", -"spece", -"special", -"specie", -"species", -"specify", -"speck", -"specked", -"speckle", -"speckly", -"specks", -"specky", -"specs", -"specter", -"spectra", -"spectry", -"specula", -"specus", -"sped", -"speech", -"speed", -"speeder", -"speedy", -"speel", -"speen", -"speer", -"speiss", -"spelder", -"spelk", -"spell", -"speller", -"spelt", -"spelter", -"speltz", -"spelunk", -"spence", -"spencer", -"spend", -"spender", -"spense", -"spent", -"speos", -"sperate", -"sperity", -"sperket", -"sperm", -"sperma", -"spermic", -"spermy", -"sperone", -"spet", -"spetch", -"spew", -"spewer", -"spewing", -"spewy", -"spex", -"sphacel", -"sphecid", -"spheges", -"sphegid", -"sphene", -"sphenic", -"spheral", -"sphere", -"spheric", -"sphery", -"sphinx", -"spica", -"spical", -"spicant", -"spicate", -"spice", -"spiced", -"spicer", -"spicery", -"spicily", -"spicing", -"spick", -"spicket", -"spickle", -"spicose", -"spicous", -"spicula", -"spicule", -"spicy", -"spider", -"spidery", -"spidger", -"spied", -"spiegel", -"spiel", -"spieler", -"spier", -"spiff", -"spiffed", -"spiffy", -"spig", -"spignet", -"spigot", -"spike", -"spiked", -"spiker", -"spikily", -"spiking", -"spiky", -"spile", -"spiler", -"spiling", -"spilite", -"spill", -"spiller", -"spillet", -"spilly", -"spiloma", -"spilt", -"spilth", -"spilus", -"spin", -"spina", -"spinach", -"spinae", -"spinage", -"spinal", -"spinate", -"spinder", -"spindle", -"spindly", -"spine", -"spined", -"spinel", -"spinet", -"spingel", -"spink", -"spinner", -"spinney", -"spinoid", -"spinose", -"spinous", -"spinule", -"spiny", -"spionid", -"spiral", -"spirale", -"spiran", -"spirant", -"spirate", -"spire", -"spirea", -"spired", -"spireme", -"spiring", -"spirit", -"spirity", -"spirket", -"spiro", -"spiroid", -"spirous", -"spirt", -"spiry", -"spise", -"spit", -"spital", -"spitbox", -"spite", -"spitful", -"spitish", -"spitted", -"spitten", -"spitter", -"spittle", -"spitz", -"spiv", -"spivery", -"splash", -"splashy", -"splat", -"splatch", -"splay", -"splayed", -"splayer", -"spleen", -"spleeny", -"spleet", -"splenic", -"splet", -"splice", -"splicer", -"spline", -"splint", -"splinty", -"split", -"splodge", -"splodgy", -"splore", -"splosh", -"splotch", -"splunge", -"splurge", -"splurgy", -"splurt", -"spoach", -"spode", -"spodium", -"spoffle", -"spoffy", -"spogel", -"spoil", -"spoiled", -"spoiler", -"spoilt", -"spoke", -"spoken", -"spoky", -"spole", -"spolia", -"spolium", -"spondee", -"spondyl", -"spong", -"sponge", -"sponged", -"sponger", -"spongin", -"spongy", -"sponsal", -"sponson", -"sponsor", -"spoof", -"spoofer", -"spook", -"spooky", -"spool", -"spooler", -"spoom", -"spoon", -"spooner", -"spoony", -"spoor", -"spoorer", -"spoot", -"spor", -"sporal", -"spore", -"spored", -"sporid", -"sporoid", -"sporont", -"sporous", -"sporran", -"sport", -"sporter", -"sportly", -"sports", -"sporty", -"sporule", -"sposh", -"sposhy", -"spot", -"spotted", -"spotter", -"spottle", -"spotty", -"spousal", -"spouse", -"spousy", -"spout", -"spouter", -"spouty", -"sprack", -"sprad", -"sprag", -"spraich", -"sprain", -"spraint", -"sprang", -"sprank", -"sprat", -"spratty", -"sprawl", -"sprawly", -"spray", -"sprayer", -"sprayey", -"spread", -"spready", -"spreath", -"spree", -"spreeuw", -"spreng", -"sprent", -"spret", -"sprew", -"sprewl", -"spried", -"sprier", -"spriest", -"sprig", -"spriggy", -"spring", -"springe", -"springy", -"sprink", -"sprint", -"sprit", -"sprite", -"spritty", -"sproat", -"sprod", -"sprogue", -"sproil", -"sprong", -"sprose", -"sprout", -"sprowsy", -"spruce", -"sprue", -"spruer", -"sprug", -"spruit", -"sprung", -"sprunny", -"sprunt", -"spry", -"spryly", -"spud", -"spudder", -"spuddle", -"spuddy", -"spuffle", -"spug", -"spuke", -"spume", -"spumone", -"spumose", -"spumous", -"spumy", -"spun", -"spung", -"spunk", -"spunkie", -"spunky", -"spunny", -"spur", -"spurge", -"spuriae", -"spurl", -"spurlet", -"spurn", -"spurner", -"spurred", -"spurrer", -"spurry", -"spurt", -"spurter", -"spurtle", -"spurway", -"sput", -"sputa", -"sputter", -"sputum", -"spy", -"spyboat", -"spydom", -"spyer", -"spyhole", -"spyism", -"spyship", -"squab", -"squabby", -"squacco", -"squad", -"squaddy", -"squail", -"squalid", -"squall", -"squally", -"squalm", -"squalor", -"squam", -"squama", -"squamae", -"squame", -"square", -"squared", -"squarer", -"squark", -"squary", -"squash", -"squashy", -"squat", -"squatly", -"squatty", -"squaw", -"squawk", -"squawky", -"squdge", -"squdgy", -"squeak", -"squeaky", -"squeal", -"squeald", -"squeam", -"squeamy", -"squeege", -"squeeze", -"squeezy", -"squelch", -"squench", -"squib", -"squid", -"squidge", -"squidgy", -"squiffy", -"squilla", -"squin", -"squinch", -"squinny", -"squinsy", -"squint", -"squinty", -"squire", -"squiret", -"squirk", -"squirm", -"squirmy", -"squirr", -"squirt", -"squirty", -"squish", -"squishy", -"squit", -"squitch", -"squoze", -"squush", -"squushy", -"sraddha", -"sramana", -"sri", -"sruti", -"ssu", -"st", -"staab", -"stab", -"stabber", -"stabile", -"stable", -"stabler", -"stably", -"staboy", -"stacher", -"stachys", -"stack", -"stacker", -"stacte", -"stadda", -"staddle", -"stade", -"stadia", -"stadic", -"stadion", -"stadium", -"staff", -"staffed", -"staffer", -"stag", -"stage", -"staged", -"stager", -"stagery", -"stagese", -"stagger", -"staggie", -"staggy", -"stagily", -"staging", -"stagnum", -"stagy", -"staia", -"staid", -"staidly", -"stain", -"stainer", -"staio", -"stair", -"staired", -"stairy", -"staith", -"staiver", -"stake", -"staker", -"stale", -"stalely", -"staling", -"stalk", -"stalked", -"stalker", -"stalko", -"stalky", -"stall", -"stallar", -"staller", -"stam", -"stambha", -"stamen", -"stamin", -"stamina", -"stammel", -"stammer", -"stamnos", -"stamp", -"stampee", -"stamper", -"stample", -"stance", -"stanch", -"stand", -"standee", -"standel", -"stander", -"stane", -"stang", -"stanine", -"stanjen", -"stank", -"stankie", -"stannel", -"stanner", -"stannic", -"stanno", -"stannum", -"stannyl", -"stanza", -"stanze", -"stap", -"stapes", -"staple", -"stapled", -"stapler", -"star", -"starch", -"starchy", -"stardom", -"stare", -"staree", -"starer", -"starets", -"starful", -"staring", -"stark", -"starken", -"starkly", -"starky", -"starlet", -"starlit", -"starn", -"starnel", -"starnie", -"starost", -"starred", -"starry", -"start", -"starter", -"startle", -"startly", -"startor", -"starty", -"starve", -"starved", -"starver", -"starvy", -"stary", -"stases", -"stash", -"stashie", -"stasis", -"statal", -"statant", -"state", -"stated", -"stately", -"stater", -"static", -"statics", -"station", -"statism", -"statist", -"stative", -"stator", -"statue", -"statued", -"stature", -"status", -"statute", -"stauk", -"staumer", -"staun", -"staunch", -"staup", -"stauter", -"stave", -"staver", -"stavers", -"staving", -"staw", -"stawn", -"staxis", -"stay", -"stayed", -"stayer", -"staynil", -"stays", -"stchi", -"stead", -"steady", -"steak", -"steal", -"stealed", -"stealer", -"stealth", -"stealy", -"steam", -"steamer", -"steamy", -"stean", -"stearic", -"stearin", -"stearyl", -"steatin", -"stech", -"steddle", -"steed", -"steek", -"steel", -"steeler", -"steely", -"steen", -"steenth", -"steep", -"steepen", -"steeper", -"steeple", -"steeply", -"steepy", -"steer", -"steerer", -"steeve", -"steever", -"steg", -"steid", -"steigh", -"stein", -"stekan", -"stela", -"stelae", -"stelai", -"stelar", -"stele", -"stell", -"stella", -"stellar", -"stem", -"stema", -"stemlet", -"stemma", -"stemmed", -"stemmer", -"stemmy", -"stemple", -"stemson", -"sten", -"stenar", -"stench", -"stenchy", -"stencil", -"stend", -"steng", -"stengah", -"stenion", -"steno", -"stenog", -"stent", -"stenter", -"stenton", -"step", -"steppe", -"stepped", -"stepper", -"stepson", -"stept", -"stepway", -"stere", -"stereo", -"steri", -"steric", -"sterics", -"steride", -"sterile", -"sterin", -"sterk", -"sterlet", -"stern", -"sterna", -"sternad", -"sternal", -"sterned", -"sternly", -"sternum", -"stero", -"steroid", -"sterol", -"stert", -"stertor", -"sterve", -"stet", -"stetch", -"stevel", -"steven", -"stevia", -"stew", -"steward", -"stewed", -"stewpan", -"stewpot", -"stewy", -"stey", -"sthenia", -"sthenic", -"stib", -"stibial", -"stibic", -"stibine", -"stibium", -"stich", -"stichic", -"stichid", -"stick", -"sticked", -"sticker", -"stickit", -"stickle", -"stickly", -"sticks", -"stickum", -"sticky", -"stid", -"stiddy", -"stife", -"stiff", -"stiffen", -"stiffly", -"stifle", -"stifler", -"stigma", -"stigmai", -"stigmal", -"stigme", -"stile", -"stilet", -"still", -"stiller", -"stilly", -"stilt", -"stilted", -"stilter", -"stilty", -"stim", -"stime", -"stimuli", -"stimy", -"stine", -"sting", -"stinge", -"stinger", -"stingo", -"stingy", -"stink", -"stinker", -"stint", -"stinted", -"stinter", -"stinty", -"stion", -"stionic", -"stipe", -"stiped", -"stipel", -"stipend", -"stipes", -"stippen", -"stipple", -"stipply", -"stipula", -"stipule", -"stir", -"stirk", -"stirp", -"stirps", -"stirra", -"stirrer", -"stirrup", -"stitch", -"stite", -"stith", -"stithy", -"stive", -"stiver", -"stivy", -"stoa", -"stoach", -"stoat", -"stoater", -"stob", -"stocah", -"stock", -"stocker", -"stocks", -"stocky", -"stod", -"stodge", -"stodger", -"stodgy", -"stoep", -"stof", -"stoff", -"stog", -"stoga", -"stogie", -"stogy", -"stoic", -"stoical", -"stoke", -"stoker", -"stola", -"stolae", -"stole", -"stoled", -"stolen", -"stolid", -"stolist", -"stollen", -"stolon", -"stoma", -"stomach", -"stomata", -"stomate", -"stomium", -"stomp", -"stomper", -"stond", -"stone", -"stoned", -"stonen", -"stoner", -"stong", -"stonied", -"stonify", -"stonily", -"stoning", -"stonish", -"stonker", -"stony", -"stood", -"stooded", -"stooden", -"stoof", -"stooge", -"stook", -"stooker", -"stookie", -"stool", -"stoon", -"stoond", -"stoop", -"stooper", -"stoory", -"stoot", -"stop", -"stopa", -"stope", -"stoper", -"stopgap", -"stoping", -"stopped", -"stopper", -"stoppit", -"stopple", -"storage", -"storax", -"store", -"storeen", -"storer", -"storge", -"storied", -"storier", -"storify", -"stork", -"storken", -"storm", -"stormer", -"stormy", -"story", -"stosh", -"stoss", -"stot", -"stotter", -"stoun", -"stound", -"stoup", -"stour", -"stoury", -"stoush", -"stout", -"stouten", -"stouth", -"stoutly", -"stouty", -"stove", -"stoven", -"stover", -"stow", -"stowage", -"stowce", -"stower", -"stowing", -"stra", -"strack", -"stract", -"strad", -"strade", -"stradl", -"stradld", -"strae", -"strafe", -"strafer", -"strag", -"straik", -"strain", -"straint", -"strait", -"strake", -"straked", -"straky", -"stram", -"stramp", -"strand", -"strang", -"strange", -"strany", -"strap", -"strass", -"strata", -"stratal", -"strath", -"strati", -"stratic", -"stratum", -"stratus", -"strave", -"straw", -"strawen", -"strawer", -"strawy", -"stray", -"strayer", -"stre", -"streak", -"streaky", -"stream", -"streamy", -"streck", -"stree", -"streek", -"streel", -"streen", -"streep", -"street", -"streets", -"streite", -"streke", -"stremma", -"streng", -"strent", -"strenth", -"strepen", -"strepor", -"stress", -"stret", -"stretch", -"strette", -"stretti", -"stretto", -"strew", -"strewer", -"strewn", -"strey", -"streyne", -"stria", -"striae", -"strial", -"striate", -"strich", -"striche", -"strick", -"strict", -"strid", -"stride", -"strider", -"stridor", -"strife", -"strig", -"striga", -"strigae", -"strigal", -"stright", -"strigil", -"strike", -"striker", -"strind", -"string", -"stringy", -"striola", -"strip", -"stripe", -"striped", -"striper", -"stript", -"stripy", -"strit", -"strive", -"strived", -"striven", -"striver", -"strix", -"stroam", -"strobic", -"strode", -"stroil", -"stroke", -"stroker", -"stroky", -"strold", -"stroll", -"strolld", -"strom", -"stroma", -"stromal", -"stromb", -"strome", -"strone", -"strong", -"strook", -"stroot", -"strop", -"strophe", -"stroth", -"stroud", -"stroup", -"strove", -"strow", -"strowd", -"strown", -"stroy", -"stroyer", -"strub", -"struck", -"strudel", -"strue", -"strum", -"struma", -"strumae", -"strung", -"strunt", -"strut", -"struth", -"struv", -"strych", -"stub", -"stubb", -"stubbed", -"stubber", -"stubble", -"stubbly", -"stubboy", -"stubby", -"stuber", -"stuboy", -"stucco", -"stuck", -"stud", -"studder", -"studdie", -"studdle", -"stude", -"student", -"studia", -"studied", -"studier", -"studio", -"studium", -"study", -"stue", -"stuff", -"stuffed", -"stuffer", -"stuffy", -"stug", -"stuggy", -"stuiver", -"stull", -"stuller", -"stulm", -"stum", -"stumble", -"stumbly", -"stumer", -"stummer", -"stummy", -"stump", -"stumper", -"stumpy", -"stun", -"stung", -"stunk", -"stunner", -"stunsle", -"stunt", -"stunted", -"stunter", -"stunty", -"stupa", -"stupe", -"stupefy", -"stupend", -"stupent", -"stupex", -"stupid", -"stupor", -"stupose", -"stupp", -"stuprum", -"sturdy", -"sturine", -"sturk", -"sturt", -"sturtan", -"sturtin", -"stuss", -"stut", -"stutter", -"sty", -"styan", -"styca", -"styful", -"stylar", -"stylate", -"style", -"styler", -"stylet", -"styline", -"styling", -"stylish", -"stylist", -"stylite", -"stylize", -"stylo", -"styloid", -"stylops", -"stylus", -"stymie", -"stypsis", -"styptic", -"styrax", -"styrene", -"styrol", -"styrone", -"styryl", -"stythe", -"styward", -"suable", -"suably", -"suade", -"suaharo", -"suant", -"suantly", -"suasion", -"suasive", -"suasory", -"suave", -"suavely", -"suavify", -"suavity", -"sub", -"subacid", -"subact", -"subage", -"subah", -"subaid", -"subanal", -"subarch", -"subarea", -"subatom", -"subaud", -"subband", -"subbank", -"subbase", -"subbass", -"subbeau", -"subbias", -"subbing", -"subcase", -"subcash", -"subcast", -"subcell", -"subcity", -"subclan", -"subcool", -"subdate", -"subdean", -"subdeb", -"subdial", -"subdie", -"subdual", -"subduce", -"subduct", -"subdue", -"subdued", -"subduer", -"subecho", -"subedit", -"suber", -"suberic", -"suberin", -"subface", -"subfeu", -"subfief", -"subfix", -"subform", -"subfusc", -"subfusk", -"subgape", -"subgens", -"subget", -"subgit", -"subgod", -"subgrin", -"subgyre", -"subhall", -"subhead", -"subherd", -"subhero", -"subicle", -"subidar", -"subidea", -"subitem", -"subjack", -"subject", -"subjee", -"subjoin", -"subking", -"sublate", -"sublet", -"sublid", -"sublime", -"sublong", -"sublot", -"submaid", -"submain", -"subman", -"submind", -"submiss", -"submit", -"subnect", -"subness", -"subnex", -"subnote", -"subnude", -"suboral", -"suborn", -"suboval", -"subpart", -"subpass", -"subpial", -"subpimp", -"subplat", -"subplot", -"subplow", -"subpool", -"subport", -"subrace", -"subrent", -"subroot", -"subrule", -"subsale", -"subsalt", -"subsea", -"subsect", -"subsept", -"subset", -"subside", -"subsidy", -"subsill", -"subsist", -"subsoil", -"subsult", -"subsume", -"subtack", -"subtend", -"subtext", -"subtile", -"subtill", -"subtle", -"subtly", -"subtone", -"subtype", -"subunit", -"suburb", -"subvein", -"subvene", -"subvert", -"subvola", -"subway", -"subwink", -"subzone", -"succade", -"succeed", -"succent", -"success", -"succi", -"succin", -"succise", -"succor", -"succory", -"succous", -"succub", -"succuba", -"succube", -"succula", -"succumb", -"succuss", -"such", -"suck", -"suckage", -"sucken", -"sucker", -"sucking", -"suckle", -"suckler", -"suclat", -"sucrate", -"sucre", -"sucrose", -"suction", -"sucuri", -"sucuriu", -"sud", -"sudamen", -"sudary", -"sudate", -"sudd", -"sudden", -"sudder", -"suddle", -"suddy", -"sudoral", -"sudoric", -"suds", -"sudsman", -"sudsy", -"sue", -"suede", -"suer", -"suet", -"suety", -"suff", -"suffect", -"suffer", -"suffete", -"suffice", -"suffix", -"sufflue", -"suffuse", -"sugamo", -"sugan", -"sugar", -"sugared", -"sugarer", -"sugary", -"sugent", -"suggest", -"sugh", -"sugi", -"suguaro", -"suhuaro", -"suicide", -"suid", -"suidian", -"suiform", -"suimate", -"suine", -"suing", -"suingly", -"suint", -"suist", -"suit", -"suite", -"suiting", -"suitor", -"suity", -"suji", -"sulcal", -"sulcar", -"sulcate", -"sulcus", -"suld", -"sulea", -"sulfa", -"sulfato", -"sulfion", -"sulfury", -"sulk", -"sulka", -"sulker", -"sulkily", -"sulky", -"sull", -"sulla", -"sullage", -"sullen", -"sullow", -"sully", -"sulpha", -"sulpho", -"sulphur", -"sultam", -"sultan", -"sultana", -"sultane", -"sultone", -"sultry", -"sulung", -"sum", -"sumac", -"sumatra", -"sumbul", -"sumless", -"summage", -"summand", -"summar", -"summary", -"summate", -"summed", -"summer", -"summery", -"summist", -"summit", -"summity", -"summon", -"summons", -"summula", -"summut", -"sumner", -"sump", -"sumpage", -"sumper", -"sumph", -"sumphy", -"sumpit", -"sumple", -"sumpman", -"sumpter", -"sun", -"sunbeam", -"sunbird", -"sunbow", -"sunburn", -"suncup", -"sundae", -"sundang", -"sundari", -"sundek", -"sunder", -"sundew", -"sundial", -"sundik", -"sundog", -"sundown", -"sundra", -"sundri", -"sundry", -"sune", -"sunfall", -"sunfast", -"sunfish", -"sung", -"sungha", -"sunglo", -"sunglow", -"sunk", -"sunken", -"sunket", -"sunlamp", -"sunland", -"sunless", -"sunlet", -"sunlike", -"sunlit", -"sunn", -"sunnily", -"sunnud", -"sunny", -"sunray", -"sunrise", -"sunroom", -"sunset", -"sunsmit", -"sunspot", -"sunt", -"sunup", -"sunward", -"sunway", -"sunways", -"sunweed", -"sunwise", -"sunyie", -"sup", -"supa", -"supari", -"supawn", -"supe", -"super", -"superb", -"supine", -"supper", -"supping", -"supple", -"supply", -"support", -"suppose", -"suppost", -"supreme", -"sur", -"sura", -"surah", -"surahi", -"sural", -"suranal", -"surat", -"surbase", -"surbate", -"surbed", -"surcoat", -"surcrue", -"surculi", -"surd", -"surdent", -"surdity", -"sure", -"surely", -"sures", -"surette", -"surety", -"surf", -"surface", -"surfacy", -"surfeit", -"surfer", -"surfle", -"surfman", -"surfuse", -"surfy", -"surge", -"surgent", -"surgeon", -"surgery", -"surging", -"surgy", -"suriga", -"surlily", -"surly", -"surma", -"surmark", -"surmise", -"surname", -"surnap", -"surnay", -"surpass", -"surplus", -"surra", -"surrey", -"surtax", -"surtout", -"survey", -"survive", -"suscept", -"susi", -"suslik", -"suspect", -"suspend", -"suspire", -"sustain", -"susu", -"susurr", -"suther", -"sutile", -"sutler", -"sutlery", -"sutor", -"sutra", -"suttee", -"sutten", -"suttin", -"suttle", -"sutural", -"suture", -"suum", -"suwarro", -"suwe", -"suz", -"svelte", -"swa", -"swab", -"swabber", -"swabble", -"swack", -"swacken", -"swad", -"swaddle", -"swaddy", -"swag", -"swage", -"swager", -"swagger", -"swaggie", -"swaggy", -"swagman", -"swain", -"swaird", -"swale", -"swaler", -"swaling", -"swallet", -"swallo", -"swallow", -"swam", -"swami", -"swamp", -"swamper", -"swampy", -"swan", -"swang", -"swangy", -"swank", -"swanker", -"swanky", -"swanner", -"swanny", -"swap", -"swape", -"swapper", -"swaraj", -"swarbie", -"sward", -"swardy", -"sware", -"swarf", -"swarfer", -"swarm", -"swarmer", -"swarmy", -"swarry", -"swart", -"swarth", -"swarthy", -"swartly", -"swarty", -"swarve", -"swash", -"swasher", -"swashy", -"swat", -"swatch", -"swath", -"swathe", -"swather", -"swathy", -"swatter", -"swattle", -"swaver", -"sway", -"swayed", -"swayer", -"swayful", -"swaying", -"sweal", -"swear", -"swearer", -"sweat", -"sweated", -"sweater", -"sweath", -"sweaty", -"swedge", -"sweeny", -"sweep", -"sweeper", -"sweepy", -"sweer", -"sweered", -"sweet", -"sweeten", -"sweetie", -"sweetly", -"sweety", -"swego", -"swell", -"swelled", -"sweller", -"swelly", -"swelp", -"swelt", -"swelter", -"swelth", -"sweltry", -"swelty", -"swep", -"swept", -"swerd", -"swerve", -"swerver", -"swick", -"swidge", -"swift", -"swiften", -"swifter", -"swifty", -"swig", -"swigger", -"swiggle", -"swile", -"swill", -"swiller", -"swim", -"swimmer", -"swimmy", -"swimy", -"swindle", -"swine", -"swinely", -"swinery", -"swiney", -"swing", -"swinge", -"swinger", -"swingle", -"swingy", -"swinish", -"swink", -"swinney", -"swipe", -"swiper", -"swipes", -"swiple", -"swipper", -"swipy", -"swird", -"swire", -"swirl", -"swirly", -"swish", -"swisher", -"swishy", -"swiss", -"switch", -"switchy", -"swith", -"swithe", -"swithen", -"swither", -"swivel", -"swivet", -"swiz", -"swizzle", -"swob", -"swollen", -"swom", -"swonken", -"swoon", -"swooned", -"swoony", -"swoop", -"swooper", -"swoosh", -"sword", -"swore", -"sworn", -"swosh", -"swot", -"swotter", -"swounds", -"swow", -"swum", -"swung", -"swungen", -"swure", -"syagush", -"sybotic", -"syce", -"sycee", -"sycock", -"sycoma", -"syconid", -"syconus", -"sycosis", -"sye", -"syenite", -"sylid", -"syllab", -"syllabe", -"syllabi", -"sylloge", -"sylph", -"sylphic", -"sylphid", -"sylphy", -"sylva", -"sylvae", -"sylvage", -"sylvan", -"sylvate", -"sylvic", -"sylvine", -"sylvite", -"symbion", -"symbiot", -"symbol", -"sympode", -"symptom", -"synacme", -"synacmy", -"synange", -"synapse", -"synapte", -"synaxar", -"synaxis", -"sync", -"syncarp", -"synch", -"synchro", -"syncope", -"syndic", -"syndoc", -"syne", -"synema", -"synergy", -"synesis", -"syngamy", -"synod", -"synodal", -"synoecy", -"synonym", -"synopsy", -"synovia", -"syntan", -"syntax", -"synthol", -"syntomy", -"syntone", -"syntony", -"syntype", -"synusia", -"sypher", -"syre", -"syringa", -"syringe", -"syrinx", -"syrma", -"syrphid", -"syrt", -"syrtic", -"syrup", -"syruped", -"syruper", -"syrupy", -"syssel", -"system", -"systole", -"systyle", -"syzygy", -"t", -"ta", -"taa", -"taar", -"tab", -"tabacin", -"tabacum", -"tabanid", -"tabard", -"tabaret", -"tabaxir", -"tabber", -"tabby", -"tabefy", -"tabella", -"taberna", -"tabes", -"tabet", -"tabetic", -"tabic", -"tabid", -"tabidly", -"tabific", -"tabinet", -"tabla", -"table", -"tableau", -"tabled", -"tabler", -"tables", -"tablet", -"tabling", -"tabloid", -"tabog", -"taboo", -"taboot", -"tabor", -"taborer", -"taboret", -"taborin", -"tabour", -"tabret", -"tabu", -"tabula", -"tabular", -"tabule", -"tabut", -"taccada", -"tach", -"tache", -"tachiol", -"tacit", -"tacitly", -"tack", -"tacker", -"tacket", -"tackety", -"tackey", -"tacking", -"tackle", -"tackled", -"tackler", -"tacky", -"tacnode", -"tacso", -"tact", -"tactful", -"tactic", -"tactics", -"tactile", -"taction", -"tactite", -"tactive", -"tactor", -"tactual", -"tactus", -"tad", -"tade", -"tadpole", -"tae", -"tael", -"taen", -"taenia", -"taenial", -"taenian", -"taenite", -"taennin", -"taffeta", -"taffety", -"taffle", -"taffy", -"tafia", -"taft", -"tafwiz", -"tag", -"tagetol", -"tagged", -"tagger", -"taggle", -"taggy", -"taglet", -"taglike", -"taglock", -"tagrag", -"tagsore", -"tagtail", -"tagua", -"taguan", -"tagwerk", -"taha", -"taheen", -"tahil", -"tahin", -"tahr", -"tahsil", -"tahua", -"tai", -"taiaha", -"taich", -"taiga", -"taigle", -"taihoa", -"tail", -"tailage", -"tailed", -"tailer", -"tailet", -"tailge", -"tailing", -"taille", -"taillie", -"tailor", -"tailory", -"tailpin", -"taily", -"tailzee", -"tailzie", -"taimen", -"tain", -"taint", -"taintor", -"taipan", -"taipo", -"tairge", -"tairger", -"tairn", -"taisch", -"taise", -"taissle", -"tait", -"taiver", -"taivers", -"taivert", -"taj", -"takable", -"takar", -"take", -"takeful", -"taken", -"taker", -"takin", -"taking", -"takings", -"takosis", -"takt", -"taky", -"takyr", -"tal", -"tala", -"talabon", -"talahib", -"talaje", -"talak", -"talao", -"talar", -"talari", -"talaria", -"talaric", -"talayot", -"talbot", -"talc", -"talcer", -"talcky", -"talcoid", -"talcose", -"talcous", -"talcum", -"tald", -"tale", -"taled", -"taleful", -"talent", -"taler", -"tales", -"tali", -"taliage", -"taliera", -"talion", -"talipat", -"taliped", -"talipes", -"talipot", -"talis", -"talisay", -"talite", -"talitol", -"talk", -"talker", -"talkful", -"talkie", -"talking", -"talky", -"tall", -"tallage", -"tallboy", -"taller", -"tallero", -"talles", -"tallet", -"talliar", -"tallier", -"tallis", -"tallish", -"tallit", -"tallith", -"talloel", -"tallote", -"tallow", -"tallowy", -"tally", -"tallyho", -"talma", -"talon", -"taloned", -"talonic", -"talonid", -"talose", -"talpid", -"talpify", -"talpine", -"talpoid", -"talthib", -"taluk", -"taluka", -"talus", -"taluto", -"talwar", -"talwood", -"tam", -"tamable", -"tamably", -"tamale", -"tamandu", -"tamanu", -"tamara", -"tamarao", -"tamarin", -"tamas", -"tamasha", -"tambac", -"tamber", -"tambo", -"tamboo", -"tambor", -"tambour", -"tame", -"tamein", -"tamely", -"tamer", -"tamis", -"tamise", -"tamlung", -"tammie", -"tammock", -"tammy", -"tamp", -"tampala", -"tampan", -"tampang", -"tamper", -"tampin", -"tamping", -"tampion", -"tampon", -"tampoon", -"tan", -"tana", -"tanach", -"tanager", -"tanaist", -"tanak", -"tanan", -"tanbark", -"tanbur", -"tancel", -"tandan", -"tandem", -"tandle", -"tandour", -"tane", -"tang", -"tanga", -"tanged", -"tangelo", -"tangent", -"tanger", -"tangham", -"tanghan", -"tanghin", -"tangi", -"tangie", -"tangka", -"tanglad", -"tangle", -"tangler", -"tangly", -"tango", -"tangram", -"tangs", -"tangue", -"tangum", -"tangun", -"tangy", -"tanh", -"tanha", -"tania", -"tanica", -"tanier", -"tanist", -"tanjib", -"tanjong", -"tank", -"tanka", -"tankage", -"tankah", -"tankard", -"tanked", -"tanker", -"tankert", -"tankful", -"tankle", -"tankman", -"tanling", -"tannage", -"tannaic", -"tannaim", -"tannase", -"tannate", -"tanned", -"tanner", -"tannery", -"tannic", -"tannide", -"tannin", -"tanning", -"tannoid", -"tannyl", -"tanoa", -"tanquam", -"tanquen", -"tanrec", -"tansy", -"tantara", -"tanti", -"tantivy", -"tantle", -"tantra", -"tantric", -"tantrik", -"tantrum", -"tantum", -"tanwood", -"tanyard", -"tanzeb", -"tanzib", -"tanzy", -"tao", -"taotai", -"taoyin", -"tap", -"tapa", -"tapalo", -"tapas", -"tapasvi", -"tape", -"tapeman", -"tapen", -"taper", -"tapered", -"taperer", -"taperly", -"tapet", -"tapetal", -"tapete", -"tapeti", -"tapetum", -"taphole", -"tapia", -"tapioca", -"tapir", -"tapis", -"tapism", -"tapist", -"taplash", -"taplet", -"tapmost", -"tapnet", -"tapoa", -"tapoun", -"tappa", -"tappall", -"tappaul", -"tappen", -"tapper", -"tappet", -"tapping", -"tappoon", -"taproom", -"taproot", -"taps", -"tapster", -"tapu", -"tapul", -"taqua", -"tar", -"tara", -"taraf", -"tarage", -"tarairi", -"tarand", -"taraph", -"tarapin", -"tarata", -"taratah", -"tarau", -"tarbet", -"tarboy", -"tarbush", -"tardily", -"tardive", -"tardle", -"tardy", -"tare", -"tarea", -"tarefa", -"tarente", -"tarfa", -"targe", -"targer", -"target", -"tarhood", -"tari", -"tarie", -"tariff", -"tarin", -"tariric", -"tarish", -"tarkhan", -"tarlike", -"tarmac", -"tarman", -"tarn", -"tarnal", -"tarnish", -"taro", -"taroc", -"tarocco", -"tarok", -"tarot", -"tarp", -"tarpan", -"tarpon", -"tarpot", -"tarpum", -"tarr", -"tarrack", -"tarras", -"tarrass", -"tarred", -"tarrer", -"tarri", -"tarrie", -"tarrier", -"tarrify", -"tarrily", -"tarrish", -"tarrock", -"tarrow", -"tarry", -"tars", -"tarsal", -"tarsale", -"tarse", -"tarsi", -"tarsia", -"tarsier", -"tarsome", -"tarsus", -"tart", -"tartago", -"tartan", -"tartana", -"tartane", -"tartar", -"tarten", -"tartish", -"tartle", -"tartlet", -"tartly", -"tartro", -"tartryl", -"tarve", -"tarweed", -"tarwood", -"taryard", -"tasajo", -"tascal", -"tasco", -"tash", -"tashie", -"tashlik", -"tashrif", -"task", -"taskage", -"tasker", -"taskit", -"taslet", -"tass", -"tassago", -"tassah", -"tassal", -"tassard", -"tasse", -"tassel", -"tassely", -"tasser", -"tasset", -"tassie", -"tassoo", -"taste", -"tasted", -"tasten", -"taster", -"tastily", -"tasting", -"tasty", -"tasu", -"tat", -"tataupa", -"tatbeb", -"tatchy", -"tate", -"tater", -"tath", -"tatie", -"tatinek", -"tatler", -"tatou", -"tatouay", -"tatsman", -"tatta", -"tatter", -"tattery", -"tatther", -"tattied", -"tatting", -"tattle", -"tattler", -"tattoo", -"tattva", -"tatty", -"tatu", -"tau", -"taught", -"taula", -"taum", -"taun", -"taunt", -"taunter", -"taupe", -"taupo", -"taupou", -"taur", -"taurean", -"taurian", -"tauric", -"taurine", -"taurite", -"tauryl", -"taut", -"tautaug", -"tauted", -"tauten", -"tautit", -"tautly", -"tautog", -"tav", -"tave", -"tavell", -"taver", -"tavern", -"tavers", -"tavert", -"tavola", -"taw", -"tawa", -"tawdry", -"tawer", -"tawery", -"tawie", -"tawite", -"tawkee", -"tawkin", -"tawn", -"tawney", -"tawnily", -"tawnle", -"tawny", -"tawpi", -"tawpie", -"taws", -"tawse", -"tawtie", -"tax", -"taxable", -"taxably", -"taxator", -"taxed", -"taxeme", -"taxemic", -"taxer", -"taxi", -"taxibus", -"taxicab", -"taximan", -"taxine", -"taxing", -"taxis", -"taxite", -"taxitic", -"taxless", -"taxman", -"taxon", -"taxor", -"taxpaid", -"taxwax", -"taxy", -"tay", -"tayer", -"tayir", -"tayra", -"taysaam", -"tazia", -"tch", -"tchai", -"tcharik", -"tchast", -"tche", -"tchick", -"tchu", -"tck", -"te", -"tea", -"teabox", -"teaboy", -"teacake", -"teacart", -"teach", -"teache", -"teacher", -"teachy", -"teacup", -"tead", -"teadish", -"teaer", -"teaey", -"teagle", -"teaish", -"teaism", -"teak", -"teal", -"tealery", -"tealess", -"team", -"teaman", -"teameo", -"teamer", -"teaming", -"teamman", -"tean", -"teanal", -"teap", -"teapot", -"teapoy", -"tear", -"tearage", -"tearcat", -"tearer", -"tearful", -"tearing", -"tearlet", -"tearoom", -"tearpit", -"teart", -"teary", -"tease", -"teasel", -"teaser", -"teashop", -"teasing", -"teasler", -"teasy", -"teat", -"teated", -"teathe", -"teather", -"teatime", -"teatman", -"teaty", -"teave", -"teaware", -"teaze", -"teazer", -"tebbet", -"tec", -"teca", -"tecali", -"tech", -"techily", -"technic", -"techous", -"techy", -"teck", -"tecomin", -"tecon", -"tectal", -"tectum", -"tecum", -"tecuma", -"ted", -"tedder", -"tedge", -"tedious", -"tedium", -"tee", -"teedle", -"teel", -"teem", -"teemer", -"teemful", -"teeming", -"teems", -"teen", -"teenage", -"teenet", -"teens", -"teensy", -"teenty", -"teeny", -"teer", -"teerer", -"teest", -"teet", -"teetan", -"teeter", -"teeth", -"teethe", -"teethy", -"teeting", -"teety", -"teevee", -"teff", -"teg", -"tegmen", -"tegmina", -"tegua", -"tegula", -"tegular", -"tegumen", -"tehseel", -"tehsil", -"teicher", -"teil", -"teind", -"teinder", -"teioid", -"tejon", -"teju", -"tekiah", -"tekke", -"tekken", -"tektite", -"tekya", -"telamon", -"telang", -"telar", -"telary", -"tele", -"teledu", -"telega", -"teleost", -"teleran", -"telergy", -"telesia", -"telesis", -"teleuto", -"televox", -"telfer", -"telford", -"teli", -"telial", -"telic", -"telical", -"telium", -"tell", -"tellach", -"tellee", -"teller", -"telling", -"tellt", -"telome", -"telomic", -"telpath", -"telpher", -"telson", -"telt", -"telurgy", -"telyn", -"temacha", -"teman", -"tembe", -"temblor", -"temenos", -"temiak", -"temin", -"temp", -"temper", -"tempera", -"tempery", -"tempest", -"tempi", -"templar", -"temple", -"templed", -"templet", -"tempo", -"tempora", -"tempre", -"tempt", -"tempter", -"temse", -"temser", -"ten", -"tenable", -"tenably", -"tenace", -"tenai", -"tenancy", -"tenant", -"tench", -"tend", -"tendant", -"tendent", -"tender", -"tending", -"tendon", -"tendour", -"tendril", -"tendron", -"tenebra", -"tenent", -"teneral", -"tenet", -"tenfold", -"teng", -"tengere", -"tengu", -"tenible", -"tenio", -"tenline", -"tenne", -"tenner", -"tennis", -"tennisy", -"tenon", -"tenoner", -"tenor", -"tenpin", -"tenrec", -"tense", -"tensely", -"tensify", -"tensile", -"tension", -"tensity", -"tensive", -"tenson", -"tensor", -"tent", -"tentage", -"tented", -"tenter", -"tentful", -"tenth", -"tenthly", -"tentigo", -"tention", -"tentlet", -"tenture", -"tenty", -"tenuate", -"tenues", -"tenuis", -"tenuity", -"tenuous", -"tenure", -"teopan", -"tepache", -"tepal", -"tepee", -"tepefy", -"tepid", -"tepidly", -"tepor", -"tequila", -"tera", -"terap", -"teras", -"terbia", -"terbic", -"terbium", -"tercel", -"tercer", -"tercet", -"tercia", -"tercine", -"tercio", -"terebic", -"terebra", -"teredo", -"terek", -"terete", -"tereu", -"terfez", -"tergal", -"tergant", -"tergite", -"tergum", -"term", -"terma", -"termage", -"termen", -"termer", -"termin", -"termine", -"termini", -"termino", -"termite", -"termly", -"termon", -"termor", -"tern", -"terna", -"ternal", -"ternar", -"ternary", -"ternate", -"terne", -"ternery", -"ternion", -"ternize", -"ternlet", -"terp", -"terpane", -"terpene", -"terpin", -"terpine", -"terrace", -"terrage", -"terrain", -"terral", -"terrane", -"terrar", -"terrene", -"terret", -"terrier", -"terrify", -"terrine", -"terron", -"terror", -"terry", -"terse", -"tersely", -"tersion", -"tertia", -"tertial", -"tertian", -"tertius", -"terton", -"tervee", -"terzina", -"terzo", -"tesack", -"teskere", -"tessara", -"tessel", -"tessera", -"test", -"testa", -"testacy", -"testar", -"testata", -"testate", -"teste", -"tested", -"testee", -"tester", -"testes", -"testify", -"testily", -"testing", -"testis", -"teston", -"testone", -"testoon", -"testor", -"testril", -"testudo", -"testy", -"tetanic", -"tetanus", -"tetany", -"tetard", -"tetch", -"tetchy", -"tete", -"tetel", -"teth", -"tether", -"tethery", -"tetra", -"tetract", -"tetrad", -"tetrane", -"tetrazo", -"tetric", -"tetrode", -"tetrole", -"tetrose", -"tetryl", -"tetter", -"tettery", -"tettix", -"teucrin", -"teufit", -"teuk", -"teviss", -"tew", -"tewel", -"tewer", -"tewit", -"tewly", -"tewsome", -"text", -"textile", -"textlet", -"textman", -"textual", -"texture", -"tez", -"tezkere", -"th", -"tha", -"thack", -"thacker", -"thakur", -"thalami", -"thaler", -"thalli", -"thallic", -"thallus", -"thameng", -"than", -"thana", -"thanage", -"thanan", -"thane", -"thank", -"thankee", -"thanker", -"thanks", -"thapes", -"thapsia", -"thar", -"tharf", -"tharm", -"that", -"thatch", -"thatchy", -"thatn", -"thats", -"thaught", -"thave", -"thaw", -"thawer", -"thawn", -"thawy", -"the", -"theah", -"theasum", -"theat", -"theater", -"theatry", -"theave", -"theb", -"theca", -"thecae", -"thecal", -"thecate", -"thecia", -"thecium", -"thecla", -"theclan", -"thecoid", -"thee", -"theek", -"theeker", -"theelin", -"theelol", -"theer", -"theet", -"theezan", -"theft", -"thegn", -"thegnly", -"theine", -"their", -"theirn", -"theirs", -"theism", -"theist", -"thelium", -"them", -"thema", -"themata", -"theme", -"themer", -"themis", -"themsel", -"then", -"thenal", -"thenar", -"thence", -"theody", -"theorbo", -"theorem", -"theoria", -"theoric", -"theorum", -"theory", -"theow", -"therapy", -"there", -"thereas", -"thereat", -"thereby", -"therein", -"thereof", -"thereon", -"theres", -"therese", -"thereto", -"thereup", -"theriac", -"therial", -"therm", -"thermae", -"thermal", -"thermic", -"thermit", -"thermo", -"thermos", -"theroid", -"these", -"theses", -"thesial", -"thesis", -"theta", -"thetch", -"thetic", -"thetics", -"thetin", -"thetine", -"theurgy", -"thew", -"thewed", -"thewy", -"they", -"theyll", -"theyre", -"thiamin", -"thiasi", -"thiasoi", -"thiasos", -"thiasus", -"thick", -"thicken", -"thicket", -"thickly", -"thief", -"thienyl", -"thieve", -"thiever", -"thig", -"thigger", -"thigh", -"thighed", -"thight", -"thilk", -"thill", -"thiller", -"thilly", -"thimber", -"thimble", -"thin", -"thine", -"thing", -"thingal", -"thingly", -"thingum", -"thingy", -"think", -"thinker", -"thinly", -"thinner", -"thio", -"thiol", -"thiolic", -"thionic", -"thionyl", -"thir", -"third", -"thirdly", -"thirl", -"thirst", -"thirsty", -"thirt", -"thirty", -"this", -"thishow", -"thisn", -"thissen", -"thistle", -"thistly", -"thither", -"thiuram", -"thivel", -"thixle", -"tho", -"thob", -"thocht", -"thof", -"thoft", -"thoke", -"thokish", -"thole", -"tholi", -"tholoi", -"tholos", -"tholus", -"thon", -"thonder", -"thone", -"thong", -"thonged", -"thongy", -"thoo", -"thooid", -"thoom", -"thoral", -"thorax", -"thore", -"thoria", -"thoric", -"thorina", -"thorite", -"thorium", -"thorn", -"thorned", -"thornen", -"thorny", -"thoro", -"thoron", -"thorp", -"thort", -"thorter", -"those", -"thou", -"though", -"thought", -"thouse", -"thow", -"thowel", -"thowt", -"thrack", -"thraep", -"thrail", -"thrain", -"thrall", -"thram", -"thrang", -"thrap", -"thrash", -"thrast", -"thrave", -"thraver", -"thraw", -"thrawn", -"thread", -"thready", -"threap", -"threat", -"three", -"threne", -"threnos", -"threose", -"thresh", -"threw", -"thrice", -"thrift", -"thrifty", -"thrill", -"thrilly", -"thrimp", -"thring", -"thrip", -"thripel", -"thrips", -"thrive", -"thriven", -"thriver", -"thro", -"throat", -"throaty", -"throb", -"throck", -"throddy", -"throe", -"thronal", -"throne", -"throng", -"throu", -"throuch", -"through", -"throve", -"throw", -"thrower", -"thrown", -"thrum", -"thrummy", -"thrush", -"thrushy", -"thrust", -"thrutch", -"thruv", -"thrymsa", -"thud", -"thug", -"thugdom", -"thuggee", -"thujene", -"thujin", -"thujone", -"thujyl", -"thulia", -"thulir", -"thulite", -"thulium", -"thulr", -"thuluth", -"thumb", -"thumbed", -"thumber", -"thumble", -"thumby", -"thump", -"thumper", -"thunder", -"thung", -"thunge", -"thuoc", -"thurify", -"thurl", -"thurm", -"thurmus", -"thurse", -"thurt", -"thus", -"thusly", -"thutter", -"thwack", -"thwaite", -"thwart", -"thwite", -"thy", -"thyine", -"thymate", -"thyme", -"thymele", -"thymene", -"thymic", -"thymine", -"thymol", -"thymoma", -"thymus", -"thymy", -"thymyl", -"thynnid", -"thyroid", -"thyrse", -"thyrsus", -"thysel", -"thyself", -"thysen", -"ti", -"tiang", -"tiao", -"tiar", -"tiara", -"tib", -"tibby", -"tibet", -"tibey", -"tibia", -"tibiad", -"tibiae", -"tibial", -"tibiale", -"tiburon", -"tic", -"tical", -"ticca", -"tice", -"ticer", -"tick", -"ticked", -"ticken", -"ticker", -"ticket", -"tickey", -"tickie", -"ticking", -"tickle", -"tickled", -"tickler", -"tickly", -"tickney", -"ticky", -"ticul", -"tid", -"tidal", -"tidally", -"tidbit", -"tiddle", -"tiddler", -"tiddley", -"tiddy", -"tide", -"tided", -"tideful", -"tidely", -"tideway", -"tidily", -"tiding", -"tidings", -"tidley", -"tidy", -"tidyism", -"tie", -"tieback", -"tied", -"tien", -"tiepin", -"tier", -"tierce", -"tierced", -"tiered", -"tierer", -"tietick", -"tiewig", -"tiff", -"tiffany", -"tiffie", -"tiffin", -"tiffish", -"tiffle", -"tiffy", -"tift", -"tifter", -"tig", -"tige", -"tigella", -"tigelle", -"tiger", -"tigerly", -"tigery", -"tigger", -"tight", -"tighten", -"tightly", -"tights", -"tiglic", -"tignum", -"tigress", -"tigrine", -"tigroid", -"tigtag", -"tikka", -"tikker", -"tiklin", -"tikor", -"tikur", -"til", -"tilaite", -"tilaka", -"tilbury", -"tilde", -"tile", -"tiled", -"tiler", -"tilery", -"tilikum", -"tiling", -"till", -"tillage", -"tiller", -"tilley", -"tillite", -"tillot", -"tilly", -"tilmus", -"tilpah", -"tilt", -"tilter", -"tilth", -"tilting", -"tiltup", -"tilty", -"tilyer", -"timable", -"timar", -"timarau", -"timawa", -"timbal", -"timbale", -"timbang", -"timbe", -"timber", -"timbern", -"timbery", -"timbo", -"timbre", -"timbrel", -"time", -"timed", -"timeful", -"timely", -"timeous", -"timer", -"times", -"timid", -"timidly", -"timing", -"timish", -"timist", -"timon", -"timor", -"timothy", -"timpani", -"timpano", -"tin", -"tinamou", -"tincal", -"tinchel", -"tinclad", -"tinct", -"tind", -"tindal", -"tindalo", -"tinder", -"tindery", -"tine", -"tinea", -"tineal", -"tinean", -"tined", -"tineid", -"tineine", -"tineman", -"tineoid", -"tinety", -"tinful", -"ting", -"tinge", -"tinged", -"tinger", -"tingi", -"tingid", -"tingle", -"tingler", -"tingly", -"tinguy", -"tinhorn", -"tinily", -"tining", -"tink", -"tinker", -"tinkle", -"tinkler", -"tinkly", -"tinlet", -"tinlike", -"tinman", -"tinned", -"tinner", -"tinnery", -"tinnet", -"tinnily", -"tinning", -"tinnock", -"tinny", -"tinosa", -"tinsel", -"tinsman", -"tint", -"tinta", -"tintage", -"tinted", -"tinter", -"tintie", -"tinting", -"tintist", -"tinty", -"tintype", -"tinwald", -"tinware", -"tinwork", -"tiny", -"tip", -"tipburn", -"tipcart", -"tipcat", -"tipe", -"tipful", -"tiphead", -"tipiti", -"tiple", -"tipless", -"tiplet", -"tipman", -"tipmost", -"tiponi", -"tipped", -"tippee", -"tipper", -"tippet", -"tipping", -"tipple", -"tippler", -"tipply", -"tippy", -"tipsify", -"tipsily", -"tipster", -"tipsy", -"tiptail", -"tiptilt", -"tiptoe", -"tiptop", -"tipulid", -"tipup", -"tirade", -"tiralee", -"tire", -"tired", -"tiredly", -"tiredom", -"tireman", -"tirer", -"tiriba", -"tiring", -"tirl", -"tirma", -"tirr", -"tirret", -"tirrlie", -"tirve", -"tirwit", -"tisane", -"tisar", -"tissual", -"tissue", -"tissued", -"tissuey", -"tiswin", -"tit", -"titania", -"titanic", -"titano", -"titanyl", -"titar", -"titbit", -"tite", -"titer", -"titfish", -"tithal", -"tithe", -"tither", -"tithing", -"titi", -"titian", -"titien", -"titlark", -"title", -"titled", -"titler", -"titlike", -"titling", -"titlist", -"titmal", -"titman", -"titoki", -"titrate", -"titre", -"titter", -"tittery", -"tittie", -"tittle", -"tittler", -"tittup", -"tittupy", -"titty", -"titular", -"titule", -"titulus", -"tiver", -"tivoli", -"tivy", -"tiza", -"tizeur", -"tizzy", -"tji", -"tjosite", -"tlaco", -"tmema", -"tmesis", -"to", -"toa", -"toad", -"toadeat", -"toader", -"toadery", -"toadess", -"toadier", -"toadish", -"toadlet", -"toady", -"toast", -"toastee", -"toaster", -"toasty", -"toat", -"toatoa", -"tobacco", -"tobe", -"tobine", -"tobira", -"toby", -"tobyman", -"toccata", -"tocher", -"tock", -"toco", -"tocome", -"tocsin", -"tocusso", -"tod", -"today", -"todder", -"toddick", -"toddite", -"toddle", -"toddler", -"toddy", -"tode", -"tody", -"toe", -"toecap", -"toed", -"toeless", -"toelike", -"toenail", -"toetoe", -"toff", -"toffee", -"toffing", -"toffish", -"toffy", -"toft", -"tofter", -"toftman", -"tofu", -"tog", -"toga", -"togaed", -"togata", -"togate", -"togated", -"toggel", -"toggery", -"toggle", -"toggler", -"togless", -"togs", -"togt", -"togue", -"toher", -"toheroa", -"toho", -"tohunga", -"toi", -"toil", -"toiled", -"toiler", -"toilet", -"toilful", -"toiling", -"toise", -"toit", -"toitish", -"toity", -"tokay", -"toke", -"token", -"tokened", -"toko", -"tokopat", -"tol", -"tolan", -"tolane", -"told", -"toldo", -"tole", -"tolite", -"toll", -"tollage", -"toller", -"tollery", -"tolling", -"tollman", -"tolly", -"tolsey", -"tolt", -"tolter", -"tolu", -"toluate", -"toluene", -"toluic", -"toluide", -"toluido", -"toluol", -"toluyl", -"tolyl", -"toman", -"tomato", -"tomb", -"tombac", -"tombal", -"tombe", -"tombic", -"tomblet", -"tombola", -"tombolo", -"tomboy", -"tomcat", -"tomcod", -"tome", -"tomeful", -"tomelet", -"toment", -"tomfool", -"tomial", -"tomin", -"tomish", -"tomium", -"tomjohn", -"tomkin", -"tommy", -"tomnoup", -"tomorn", -"tomosis", -"tompon", -"tomtate", -"tomtit", -"ton", -"tonal", -"tonally", -"tonant", -"tondino", -"tone", -"toned", -"toneme", -"toner", -"tonetic", -"tong", -"tonga", -"tonger", -"tongman", -"tongs", -"tongue", -"tongued", -"tonguer", -"tonguey", -"tonic", -"tonify", -"tonight", -"tonish", -"tonite", -"tonjon", -"tonk", -"tonkin", -"tonlet", -"tonnage", -"tonneau", -"tonner", -"tonnish", -"tonous", -"tonsil", -"tonsor", -"tonsure", -"tontine", -"tonus", -"tony", -"too", -"toodle", -"took", -"tooken", -"tool", -"toolbox", -"tooler", -"tooling", -"toolman", -"toom", -"toomly", -"toon", -"toop", -"toorie", -"toorock", -"tooroo", -"toosh", -"toot", -"tooter", -"tooth", -"toothed", -"toother", -"toothy", -"tootle", -"tootler", -"tootsy", -"toozle", -"toozoo", -"top", -"toparch", -"topass", -"topaz", -"topazy", -"topcap", -"topcast", -"topcoat", -"tope", -"topee", -"topeng", -"topepo", -"toper", -"topfull", -"toph", -"tophus", -"topi", -"topia", -"topiary", -"topic", -"topical", -"topknot", -"topless", -"toplike", -"topline", -"topman", -"topmast", -"topmost", -"topo", -"toponym", -"topped", -"topper", -"topping", -"topple", -"toppler", -"topply", -"toppy", -"toprail", -"toprope", -"tops", -"topsail", -"topside", -"topsl", -"topsman", -"topsoil", -"toptail", -"topwise", -"toque", -"tor", -"tora", -"torah", -"toral", -"toran", -"torc", -"torcel", -"torch", -"torcher", -"torchon", -"tore", -"tored", -"torero", -"torfel", -"torgoch", -"toric", -"torii", -"torma", -"tormen", -"torment", -"tormina", -"torn", -"tornade", -"tornado", -"tornal", -"tornese", -"torney", -"tornote", -"tornus", -"toro", -"toroid", -"torose", -"torous", -"torpedo", -"torpent", -"torpid", -"torpify", -"torpor", -"torque", -"torqued", -"torques", -"torrefy", -"torrent", -"torrid", -"torsade", -"torse", -"torsel", -"torsile", -"torsion", -"torsive", -"torsk", -"torso", -"tort", -"torta", -"torteau", -"tortile", -"tortive", -"tortula", -"torture", -"toru", -"torula", -"torulin", -"torulus", -"torus", -"torve", -"torvid", -"torvity", -"torvous", -"tory", -"tosh", -"tosher", -"toshery", -"toshly", -"toshy", -"tosily", -"toss", -"tosser", -"tossily", -"tossing", -"tosspot", -"tossup", -"tossy", -"tost", -"toston", -"tosy", -"tot", -"total", -"totally", -"totara", -"totchka", -"tote", -"totem", -"totemic", -"totemy", -"toter", -"tother", -"totient", -"toto", -"totora", -"totquot", -"totter", -"tottery", -"totting", -"tottle", -"totty", -"totuava", -"totum", -"toty", -"totyman", -"tou", -"toucan", -"touch", -"touched", -"toucher", -"touchy", -"toug", -"tough", -"toughen", -"toughly", -"tought", -"tould", -"toumnah", -"toup", -"toupee", -"toupeed", -"toupet", -"tour", -"touraco", -"tourer", -"touring", -"tourism", -"tourist", -"tourize", -"tourn", -"tournay", -"tournee", -"tourney", -"tourte", -"tousche", -"touse", -"touser", -"tousle", -"tously", -"tousy", -"tout", -"touter", -"tovar", -"tow", -"towable", -"towage", -"towai", -"towan", -"toward", -"towards", -"towboat", -"towcock", -"towd", -"towel", -"towelry", -"tower", -"towered", -"towery", -"towght", -"towhead", -"towhee", -"towing", -"towkay", -"towlike", -"towline", -"towmast", -"town", -"towned", -"townee", -"towner", -"townet", -"townful", -"townify", -"townish", -"townist", -"townlet", -"townly", -"townman", -"towny", -"towpath", -"towrope", -"towser", -"towy", -"tox", -"toxa", -"toxamin", -"toxcatl", -"toxemia", -"toxemic", -"toxic", -"toxical", -"toxicum", -"toxifer", -"toxin", -"toxity", -"toxoid", -"toxon", -"toxone", -"toxosis", -"toxotae", -"toy", -"toydom", -"toyer", -"toyful", -"toying", -"toyish", -"toyland", -"toyless", -"toylike", -"toyman", -"toyon", -"toyshop", -"toysome", -"toytown", -"toywort", -"toze", -"tozee", -"tozer", -"tra", -"trabal", -"trabant", -"trabea", -"trabeae", -"trabuch", -"trace", -"tracer", -"tracery", -"trachea", -"trachle", -"tracing", -"track", -"tracked", -"tracker", -"tract", -"tractor", -"tradal", -"trade", -"trader", -"trading", -"tradite", -"traduce", -"trady", -"traffic", -"trag", -"tragal", -"tragedy", -"tragi", -"tragic", -"tragus", -"trah", -"traheen", -"traik", -"trail", -"trailer", -"traily", -"train", -"trained", -"trainee", -"trainer", -"trainy", -"traipse", -"trait", -"traitor", -"traject", -"trajet", -"tralira", -"tram", -"trama", -"tramal", -"tramcar", -"trame", -"tramful", -"tramman", -"trammel", -"trammer", -"trammon", -"tramp", -"tramper", -"trample", -"trampot", -"tramway", -"trance", -"tranced", -"traneen", -"trank", -"tranka", -"tranker", -"trankum", -"tranky", -"transit", -"transom", -"trant", -"tranter", -"trap", -"trapes", -"trapeze", -"trapped", -"trapper", -"trappy", -"traps", -"trash", -"traship", -"trashy", -"trass", -"trasy", -"trauma", -"travail", -"travale", -"trave", -"travel", -"travis", -"travois", -"travoy", -"trawl", -"trawler", -"tray", -"trayful", -"treacle", -"treacly", -"tread", -"treader", -"treadle", -"treason", -"treat", -"treatee", -"treater", -"treator", -"treaty", -"treble", -"trebly", -"treddle", -"tree", -"treed", -"treeful", -"treeify", -"treelet", -"treeman", -"treen", -"treetop", -"treey", -"tref", -"trefle", -"trefoil", -"tregerg", -"tregohm", -"trehala", -"trek", -"trekker", -"trellis", -"tremble", -"trembly", -"tremie", -"tremolo", -"tremor", -"trenail", -"trench", -"trend", -"trendle", -"trental", -"trepan", -"trepang", -"trepid", -"tress", -"tressed", -"tresson", -"tressy", -"trest", -"trestle", -"tret", -"trevet", -"trews", -"trey", -"tri", -"triable", -"triace", -"triacid", -"triact", -"triad", -"triadic", -"triaene", -"triage", -"trial", -"triamid", -"triarch", -"triarii", -"triatic", -"triaxon", -"triazin", -"triazo", -"tribade", -"tribady", -"tribal", -"tribase", -"tribble", -"tribe", -"triblet", -"tribrac", -"tribual", -"tribuna", -"tribune", -"tribute", -"trica", -"tricae", -"tricar", -"trice", -"triceps", -"trichi", -"trichia", -"trichy", -"trick", -"tricker", -"trickle", -"trickly", -"tricksy", -"tricky", -"triclad", -"tricorn", -"tricot", -"trident", -"triduan", -"triduum", -"tried", -"triedly", -"triene", -"triens", -"trier", -"trifa", -"trifid", -"trifle", -"trifler", -"triflet", -"trifoil", -"trifold", -"trifoly", -"triform", -"trig", -"trigamy", -"trigger", -"triglid", -"triglot", -"trigly", -"trigon", -"trigone", -"trigram", -"trigyn", -"trikaya", -"trike", -"triker", -"triketo", -"trikir", -"trilabe", -"trilby", -"trilit", -"trilite", -"trilith", -"trill", -"trillet", -"trilli", -"trillo", -"trilobe", -"trilogy", -"trim", -"trimer", -"trimly", -"trimmer", -"trin", -"trinal", -"trinary", -"trindle", -"trine", -"trinely", -"tringle", -"trinity", -"trink", -"trinket", -"trinkle", -"trinode", -"trinol", -"trintle", -"trio", -"triobol", -"triode", -"triodia", -"triole", -"triolet", -"trionym", -"trior", -"triose", -"trip", -"tripal", -"tripara", -"tripart", -"tripe", -"tripel", -"tripery", -"triple", -"triplet", -"triplex", -"triplum", -"triply", -"tripod", -"tripody", -"tripoli", -"tripos", -"tripper", -"trippet", -"tripple", -"tripsis", -"tripy", -"trireme", -"trisalt", -"trisazo", -"trisect", -"triseme", -"trishna", -"trismic", -"trismus", -"trisome", -"trisomy", -"trist", -"trisul", -"trisula", -"tritaph", -"trite", -"tritely", -"tritish", -"tritium", -"tritolo", -"triton", -"tritone", -"tritor", -"trityl", -"triumph", -"triunal", -"triune", -"triurid", -"trivant", -"trivet", -"trivia", -"trivial", -"trivium", -"trivvet", -"trizoic", -"trizone", -"troat", -"troca", -"trocar", -"trochal", -"troche", -"trochee", -"trochi", -"trochid", -"trochus", -"trock", -"troco", -"trod", -"trodden", -"trode", -"troft", -"trog", -"trogger", -"troggin", -"trogon", -"trogs", -"trogue", -"troika", -"troke", -"troker", -"troll", -"troller", -"trolley", -"trollol", -"trollop", -"trolly", -"tromba", -"trombe", -"trommel", -"tromp", -"trompe", -"trompil", -"tromple", -"tron", -"trona", -"tronage", -"tronc", -"trone", -"troner", -"troolie", -"troop", -"trooper", -"troot", -"tropal", -"tropary", -"tropate", -"trope", -"tropeic", -"troper", -"trophal", -"trophi", -"trophic", -"trophy", -"tropic", -"tropine", -"tropism", -"tropist", -"tropoyl", -"tropyl", -"trot", -"troth", -"trotlet", -"trotol", -"trotter", -"trottie", -"trotty", -"trotyl", -"trouble", -"troubly", -"trough", -"troughy", -"trounce", -"troupe", -"trouper", -"trouse", -"trouser", -"trout", -"trouter", -"trouty", -"trove", -"trover", -"trow", -"trowel", -"trowing", -"trowman", -"trowth", -"troy", -"truancy", -"truant", -"trub", -"trubu", -"truce", -"trucial", -"truck", -"trucker", -"truckle", -"trucks", -"truddo", -"trudge", -"trudgen", -"trudger", -"true", -"truer", -"truff", -"truffle", -"trug", -"truish", -"truism", -"trull", -"truller", -"trullo", -"truly", -"trummel", -"trump", -"trumper", -"trumpet", -"trumph", -"trumpie", -"trun", -"truncal", -"trunch", -"trundle", -"trunk", -"trunked", -"trunnel", -"trush", -"trusion", -"truss", -"trussed", -"trusser", -"trust", -"trustee", -"trusten", -"truster", -"trustle", -"trusty", -"truth", -"truthy", -"truvat", -"try", -"trygon", -"trying", -"tryma", -"tryout", -"tryp", -"trypa", -"trypan", -"trypsin", -"tryptic", -"trysail", -"tryst", -"tryster", -"tryt", -"tsadik", -"tsamba", -"tsantsa", -"tsar", -"tsardom", -"tsarina", -"tsatlee", -"tsere", -"tsetse", -"tsia", -"tsine", -"tst", -"tsuba", -"tsubo", -"tsun", -"tsunami", -"tsungtu", -"tu", -"tua", -"tuan", -"tuarn", -"tuart", -"tuatara", -"tuatera", -"tuath", -"tub", -"tuba", -"tubae", -"tubage", -"tubal", -"tubar", -"tubate", -"tubba", -"tubbal", -"tubbeck", -"tubber", -"tubbie", -"tubbing", -"tubbish", -"tubboe", -"tubby", -"tube", -"tubeful", -"tubelet", -"tubeman", -"tuber", -"tuberin", -"tubfish", -"tubful", -"tubicen", -"tubifer", -"tubig", -"tubik", -"tubing", -"tublet", -"tublike", -"tubman", -"tubular", -"tubule", -"tubulet", -"tubuli", -"tubulus", -"tuchit", -"tuchun", -"tuck", -"tucker", -"tucket", -"tucking", -"tuckner", -"tucktoo", -"tucky", -"tucum", -"tucuma", -"tucuman", -"tudel", -"tue", -"tueiron", -"tufa", -"tufan", -"tuff", -"tuffet", -"tuffing", -"tuft", -"tufted", -"tufter", -"tuftily", -"tufting", -"tuftlet", -"tufty", -"tug", -"tugboat", -"tugger", -"tuggery", -"tugging", -"tughra", -"tugless", -"tuglike", -"tugman", -"tugrik", -"tugui", -"tui", -"tuik", -"tuille", -"tuilyie", -"tuism", -"tuition", -"tuitive", -"tuke", -"tukra", -"tula", -"tulare", -"tulasi", -"tulchan", -"tulchin", -"tule", -"tuliac", -"tulip", -"tulipy", -"tulisan", -"tulle", -"tulsi", -"tulwar", -"tum", -"tumasha", -"tumbak", -"tumble", -"tumbled", -"tumbler", -"tumbly", -"tumbrel", -"tume", -"tumefy", -"tumid", -"tumidly", -"tummals", -"tummel", -"tummer", -"tummock", -"tummy", -"tumor", -"tumored", -"tump", -"tumtum", -"tumular", -"tumuli", -"tumult", -"tumulus", -"tun", -"tuna", -"tunable", -"tunably", -"tunca", -"tund", -"tunder", -"tundish", -"tundra", -"tundun", -"tune", -"tuned", -"tuneful", -"tuner", -"tunful", -"tung", -"tungate", -"tungo", -"tunhoof", -"tunic", -"tunicin", -"tunicle", -"tuning", -"tunish", -"tunist", -"tunk", -"tunket", -"tunlike", -"tunmoot", -"tunna", -"tunnel", -"tunner", -"tunnery", -"tunnor", -"tunny", -"tuno", -"tunu", -"tuny", -"tup", -"tupara", -"tupek", -"tupelo", -"tupik", -"tupman", -"tupuna", -"tuque", -"tur", -"turacin", -"turb", -"turban", -"turbary", -"turbeh", -"turbid", -"turbine", -"turbit", -"turbith", -"turbo", -"turbot", -"turco", -"turd", -"turdine", -"turdoid", -"tureen", -"turf", -"turfage", -"turfdom", -"turfed", -"turfen", -"turfing", -"turfite", -"turfman", -"turfy", -"turgent", -"turgid", -"turgite", -"turgoid", -"turgor", -"turgy", -"turio", -"turion", -"turjite", -"turk", -"turken", -"turkey", -"turkis", -"turkle", -"turm", -"turma", -"turment", -"turmit", -"turmoil", -"turn", -"turncap", -"turndun", -"turned", -"turnel", -"turner", -"turnery", -"turney", -"turning", -"turnip", -"turnipy", -"turnix", -"turnkey", -"turnoff", -"turnout", -"turnpin", -"turnrow", -"turns", -"turnup", -"turp", -"turpeth", -"turpid", -"turps", -"turr", -"turret", -"turse", -"tursio", -"turtle", -"turtler", -"turtlet", -"turtosa", -"tururi", -"turus", -"turwar", -"tusche", -"tush", -"tushed", -"tusher", -"tushery", -"tusk", -"tuskar", -"tusked", -"tusker", -"tuskish", -"tusky", -"tussah", -"tussal", -"tusser", -"tussis", -"tussive", -"tussle", -"tussock", -"tussore", -"tussur", -"tut", -"tutania", -"tutball", -"tute", -"tutee", -"tutela", -"tutelar", -"tutenag", -"tuth", -"tutin", -"tutly", -"tutman", -"tutor", -"tutorer", -"tutorly", -"tutory", -"tutoyer", -"tutress", -"tutrice", -"tutrix", -"tuts", -"tutsan", -"tutster", -"tutti", -"tutty", -"tutu", -"tutulus", -"tutwork", -"tuwi", -"tux", -"tuxedo", -"tuyere", -"tuza", -"tuzzle", -"twa", -"twaddle", -"twaddly", -"twaddy", -"twae", -"twagger", -"twain", -"twaite", -"twal", -"twale", -"twalt", -"twang", -"twanger", -"twangle", -"twangy", -"twank", -"twanker", -"twankle", -"twanky", -"twant", -"twarly", -"twas", -"twasome", -"twat", -"twattle", -"tway", -"twazzy", -"tweag", -"tweak", -"tweaker", -"tweaky", -"twee", -"tweed", -"tweeded", -"tweedle", -"tweedy", -"tweeg", -"tweel", -"tween", -"tweeny", -"tweesh", -"tweesht", -"tweest", -"tweet", -"tweeter", -"tweeze", -"tweezer", -"tweil", -"twelfth", -"twelve", -"twenty", -"twere", -"twerp", -"twibil", -"twice", -"twicer", -"twicet", -"twick", -"twiddle", -"twiddly", -"twifoil", -"twifold", -"twig", -"twigful", -"twigged", -"twiggen", -"twigger", -"twiggy", -"twiglet", -"twilit", -"twill", -"twilled", -"twiller", -"twilly", -"twilt", -"twin", -"twindle", -"twine", -"twiner", -"twinge", -"twingle", -"twinism", -"twink", -"twinkle", -"twinkly", -"twinly", -"twinned", -"twinner", -"twinter", -"twiny", -"twire", -"twirk", -"twirl", -"twirler", -"twirly", -"twiscar", -"twisel", -"twist", -"twisted", -"twister", -"twistle", -"twisty", -"twit", -"twitch", -"twitchy", -"twite", -"twitten", -"twitter", -"twitty", -"twixt", -"twizzle", -"two", -"twofold", -"twoling", -"twoness", -"twosome", -"tychism", -"tychite", -"tycoon", -"tyddyn", -"tydie", -"tye", -"tyee", -"tyg", -"tying", -"tyke", -"tyken", -"tykhana", -"tyking", -"tylarus", -"tylion", -"tyloma", -"tylopod", -"tylose", -"tylosis", -"tylote", -"tylotic", -"tylotus", -"tylus", -"tymp", -"tympan", -"tympana", -"tympani", -"tympany", -"tynd", -"typal", -"type", -"typer", -"typeset", -"typhia", -"typhic", -"typhlon", -"typhoid", -"typhoon", -"typhose", -"typhous", -"typhus", -"typic", -"typica", -"typical", -"typicon", -"typicum", -"typify", -"typist", -"typo", -"typobar", -"typonym", -"typp", -"typy", -"tyranny", -"tyrant", -"tyre", -"tyro", -"tyroma", -"tyrone", -"tyronic", -"tyrosyl", -"tyste", -"tyt", -"tzolkin", -"tzontle", -"u", -"uang", -"uayeb", -"uberant", -"uberous", -"uberty", -"ubi", -"ubiety", -"ubiquit", -"ubussu", -"uckia", -"udal", -"udaler", -"udaller", -"udalman", -"udasi", -"udder", -"uddered", -"udell", -"udo", -"ug", -"ugh", -"uglify", -"uglily", -"ugly", -"ugsome", -"uhlan", -"uhllo", -"uhtsong", -"uily", -"uinal", -"uintjie", -"uitspan", -"uji", -"ukase", -"uke", -"ukiyoye", -"ukulele", -"ula", -"ulcer", -"ulcered", -"ulcery", -"ule", -"ulema", -"uletic", -"ulex", -"ulexine", -"ulexite", -"ulitis", -"ull", -"ulla", -"ullage", -"ullaged", -"uller", -"ulling", -"ulluco", -"ulmic", -"ulmin", -"ulminic", -"ulmo", -"ulmous", -"ulna", -"ulnad", -"ulnae", -"ulnar", -"ulnare", -"ulnaria", -"uloid", -"uloncus", -"ulster", -"ultima", -"ultimo", -"ultimum", -"ultra", -"ulu", -"ulua", -"uluhi", -"ululant", -"ululate", -"ululu", -"um", -"umbel", -"umbeled", -"umbella", -"umber", -"umbilic", -"umble", -"umbo", -"umbonal", -"umbone", -"umbones", -"umbonic", -"umbra", -"umbrae", -"umbrage", -"umbral", -"umbrel", -"umbril", -"umbrine", -"umbrose", -"umbrous", -"ume", -"umiak", -"umiri", -"umlaut", -"ump", -"umph", -"umpire", -"umpirer", -"umpteen", -"umpty", -"umu", -"un", -"unable", -"unably", -"unact", -"unacted", -"unacute", -"unadapt", -"unadd", -"unadded", -"unadopt", -"unadorn", -"unadult", -"unafire", -"unaflow", -"unaged", -"unagile", -"unaging", -"unaided", -"unaimed", -"unaired", -"unakin", -"unakite", -"unal", -"unalarm", -"unalert", -"unalike", -"unalist", -"unalive", -"unallow", -"unalone", -"unaloud", -"unamend", -"unamiss", -"unamo", -"unample", -"unamply", -"unangry", -"unannex", -"unapart", -"unapt", -"unaptly", -"unarch", -"unark", -"unarm", -"unarmed", -"unarray", -"unarted", -"unary", -"unasked", -"unau", -"unavian", -"unawake", -"unaware", -"unaway", -"unawed", -"unawful", -"unawned", -"unaxled", -"unbag", -"unbain", -"unbait", -"unbaked", -"unbale", -"unbank", -"unbar", -"unbarb", -"unbare", -"unbark", -"unbase", -"unbased", -"unbaste", -"unbated", -"unbay", -"unbe", -"unbear", -"unbeard", -"unbeast", -"unbed", -"unbefit", -"unbeget", -"unbegot", -"unbegun", -"unbeing", -"unbell", -"unbelt", -"unbench", -"unbend", -"unbent", -"unberth", -"unbeset", -"unbesot", -"unbet", -"unbias", -"unbid", -"unbind", -"unbit", -"unbitt", -"unblade", -"unbled", -"unblent", -"unbless", -"unblest", -"unblind", -"unbliss", -"unblock", -"unbloom", -"unblown", -"unblued", -"unblush", -"unboat", -"unbody", -"unbog", -"unboggy", -"unbokel", -"unbold", -"unbolt", -"unbone", -"unboned", -"unbonny", -"unboot", -"unbored", -"unborn", -"unborne", -"unbosom", -"unbound", -"unbow", -"unbowed", -"unbowel", -"unbox", -"unboxed", -"unboy", -"unbrace", -"unbraid", -"unbran", -"unbrand", -"unbrave", -"unbraze", -"unbred", -"unbrent", -"unbrick", -"unbrief", -"unbroad", -"unbroke", -"unbrown", -"unbrute", -"unbud", -"unbuild", -"unbuilt", -"unbulky", -"unbung", -"unburly", -"unburn", -"unburnt", -"unburst", -"unbury", -"unbush", -"unbusk", -"unbusy", -"unbuxom", -"unca", -"uncage", -"uncaged", -"uncake", -"uncalk", -"uncall", -"uncalm", -"uncaned", -"uncanny", -"uncap", -"uncart", -"uncase", -"uncased", -"uncask", -"uncast", -"uncaste", -"uncate", -"uncave", -"unceded", -"unchain", -"unchair", -"uncharm", -"unchary", -"uncheat", -"uncheck", -"unchid", -"unchild", -"unchurn", -"unci", -"uncia", -"uncial", -"uncinal", -"uncinch", -"uncinct", -"uncini", -"uncinus", -"uncite", -"uncited", -"uncity", -"uncivic", -"uncivil", -"unclad", -"unclamp", -"unclasp", -"unclay", -"uncle", -"unclead", -"unclean", -"unclear", -"uncleft", -"unclew", -"unclick", -"unclify", -"unclimb", -"uncling", -"unclip", -"uncloak", -"unclog", -"unclose", -"uncloud", -"unclout", -"unclub", -"unco", -"uncoach", -"uncoat", -"uncock", -"uncoded", -"uncoif", -"uncoil", -"uncoin", -"uncoked", -"uncolt", -"uncoly", -"uncome", -"uncomfy", -"uncomic", -"uncoop", -"uncope", -"uncord", -"uncore", -"uncored", -"uncork", -"uncost", -"uncouch", -"uncous", -"uncouth", -"uncover", -"uncowed", -"uncowl", -"uncoy", -"uncram", -"uncramp", -"uncream", -"uncrest", -"uncrib", -"uncried", -"uncrime", -"uncrisp", -"uncrook", -"uncropt", -"uncross", -"uncrown", -"uncrude", -"uncruel", -"unction", -"uncubic", -"uncular", -"uncurb", -"uncurd", -"uncured", -"uncurl", -"uncurse", -"uncurst", -"uncus", -"uncut", -"uncuth", -"undaily", -"undam", -"undamn", -"undared", -"undark", -"undate", -"undated", -"undaub", -"undazed", -"unde", -"undead", -"undeaf", -"undealt", -"undean", -"undear", -"undeck", -"undecyl", -"undeep", -"undeft", -"undeify", -"undelve", -"unden", -"under", -"underdo", -"underer", -"undergo", -"underly", -"undern", -"undevil", -"undewed", -"undewy", -"undid", -"undies", -"undig", -"undight", -"undiked", -"undim", -"undine", -"undined", -"undirk", -"undo", -"undock", -"undoer", -"undog", -"undoing", -"undomed", -"undon", -"undone", -"undoped", -"undose", -"undosed", -"undowny", -"undrab", -"undrag", -"undrape", -"undraw", -"undrawn", -"undress", -"undried", -"undrunk", -"undry", -"undub", -"unducal", -"undue", -"undug", -"unduke", -"undular", -"undull", -"unduly", -"unduped", -"undust", -"unduty", -"undwelt", -"undy", -"undye", -"undyed", -"undying", -"uneager", -"unearly", -"unearth", -"unease", -"uneasy", -"uneaten", -"uneath", -"unebbed", -"unedge", -"unedged", -"unelect", -"unempt", -"unempty", -"unended", -"unepic", -"unequal", -"unerect", -"unethic", -"uneven", -"unevil", -"unexact", -"uneye", -"uneyed", -"unface", -"unfaced", -"unfact", -"unfaded", -"unfain", -"unfaint", -"unfair", -"unfaith", -"unfaked", -"unfalse", -"unfamed", -"unfancy", -"unfar", -"unfast", -"unfeary", -"unfed", -"unfeed", -"unfele", -"unfelon", -"unfelt", -"unfence", -"unfeted", -"unfeued", -"unfew", -"unfiber", -"unfiend", -"unfiery", -"unfight", -"unfile", -"unfiled", -"unfill", -"unfilm", -"unfine", -"unfined", -"unfired", -"unfirm", -"unfit", -"unfitly", -"unfitty", -"unfix", -"unfixed", -"unflag", -"unflaky", -"unflank", -"unflat", -"unflead", -"unflesh", -"unflock", -"unfloor", -"unflown", -"unfluid", -"unflush", -"unfoggy", -"unfold", -"unfond", -"unfool", -"unfork", -"unform", -"unfoul", -"unfound", -"unfoxy", -"unfrail", -"unframe", -"unfrank", -"unfree", -"unfreed", -"unfret", -"unfried", -"unfrill", -"unfrizz", -"unfrock", -"unfrost", -"unfroze", -"unfull", -"unfully", -"unfumed", -"unfunny", -"unfur", -"unfurl", -"unfused", -"unfussy", -"ungag", -"ungaged", -"ungain", -"ungaite", -"ungaro", -"ungaudy", -"ungear", -"ungelt", -"unget", -"ungiant", -"ungiddy", -"ungild", -"ungill", -"ungilt", -"ungird", -"ungirt", -"ungirth", -"ungive", -"ungiven", -"ungka", -"unglad", -"unglaze", -"unglee", -"unglobe", -"ungloom", -"unglory", -"ungloss", -"unglove", -"unglue", -"unglued", -"ungnaw", -"ungnawn", -"ungod", -"ungodly", -"ungold", -"ungone", -"ungood", -"ungored", -"ungorge", -"ungot", -"ungouty", -"ungown", -"ungrace", -"ungraft", -"ungrain", -"ungrand", -"ungrasp", -"ungrave", -"ungreat", -"ungreen", -"ungrip", -"ungripe", -"ungross", -"ungrow", -"ungrown", -"ungruff", -"ungual", -"unguard", -"ungueal", -"unguent", -"ungues", -"unguis", -"ungula", -"ungulae", -"ungular", -"unguled", -"ungull", -"ungulp", -"ungum", -"unguyed", -"ungyve", -"ungyved", -"unhabit", -"unhad", -"unhaft", -"unhair", -"unhairy", -"unhand", -"unhandy", -"unhang", -"unhap", -"unhappy", -"unhard", -"unhardy", -"unharsh", -"unhasp", -"unhaste", -"unhasty", -"unhat", -"unhate", -"unhated", -"unhaunt", -"unhave", -"unhayed", -"unhazed", -"unhead", -"unheady", -"unheal", -"unheard", -"unheart", -"unheavy", -"unhedge", -"unheed", -"unheedy", -"unheld", -"unhele", -"unheler", -"unhelm", -"unherd", -"unhero", -"unhewed", -"unhewn", -"unhex", -"unhid", -"unhide", -"unhigh", -"unhinge", -"unhired", -"unhit", -"unhitch", -"unhive", -"unhoard", -"unhoary", -"unhoed", -"unhoist", -"unhold", -"unholy", -"unhome", -"unhoned", -"unhood", -"unhook", -"unhoop", -"unhoped", -"unhorny", -"unhorse", -"unhose", -"unhosed", -"unhot", -"unhouse", -"unhull", -"unhuman", -"unhumid", -"unhung", -"unhurt", -"unhusk", -"uniat", -"uniate", -"uniaxal", -"unible", -"unice", -"uniced", -"unicell", -"unicism", -"unicist", -"unicity", -"unicorn", -"unicum", -"unideal", -"unidle", -"unidly", -"unie", -"uniface", -"unific", -"unified", -"unifier", -"uniflow", -"uniform", -"unify", -"unilobe", -"unimped", -"uninked", -"uninn", -"unio", -"unioid", -"union", -"unioned", -"unionic", -"unionid", -"unioval", -"unipara", -"uniped", -"unipod", -"unique", -"unireme", -"unisoil", -"unison", -"unit", -"unitage", -"unital", -"unitary", -"unite", -"united", -"uniter", -"uniting", -"unition", -"unitism", -"unitive", -"unitize", -"unitude", -"unity", -"univied", -"unjaded", -"unjam", -"unjewel", -"unjoin", -"unjoint", -"unjolly", -"unjoyed", -"unjudge", -"unjuicy", -"unjust", -"unkamed", -"unked", -"unkempt", -"unken", -"unkept", -"unket", -"unkey", -"unkeyed", -"unkid", -"unkill", -"unkin", -"unkind", -"unking", -"unkink", -"unkirk", -"unkiss", -"unkist", -"unknave", -"unknew", -"unknit", -"unknot", -"unknow", -"unknown", -"unlace", -"unlaced", -"unlade", -"unladen", -"unlaid", -"unlame", -"unlamed", -"unland", -"unlap", -"unlarge", -"unlash", -"unlatch", -"unlath", -"unlaugh", -"unlaved", -"unlaw", -"unlawed", -"unlawly", -"unlay", -"unlead", -"unleaf", -"unleaky", -"unleal", -"unlean", -"unlearn", -"unleash", -"unleave", -"unled", -"unleft", -"unlegal", -"unlent", -"unless", -"unlet", -"unlevel", -"unlid", -"unlie", -"unlight", -"unlike", -"unliked", -"unliken", -"unlimb", -"unlime", -"unlimed", -"unlimp", -"unline", -"unlined", -"unlink", -"unlist", -"unlisty", -"unlit", -"unlive", -"unload", -"unloath", -"unlobed", -"unlocal", -"unlock", -"unlodge", -"unlofty", -"unlogic", -"unlook", -"unloop", -"unloose", -"unlord", -"unlost", -"unlousy", -"unlove", -"unloved", -"unlowly", -"unloyal", -"unlucid", -"unluck", -"unlucky", -"unlunar", -"unlured", -"unlust", -"unlusty", -"unlute", -"unluted", -"unlying", -"unmad", -"unmade", -"unmagic", -"unmaid", -"unmail", -"unmake", -"unmaker", -"unman", -"unmaned", -"unmanly", -"unmarch", -"unmarry", -"unmask", -"unmast", -"unmate", -"unmated", -"unmaze", -"unmeant", -"unmeek", -"unmeet", -"unmerge", -"unmerry", -"unmesh", -"unmet", -"unmeted", -"unmew", -"unmewed", -"unmind", -"unmined", -"unmired", -"unmiry", -"unmist", -"unmiter", -"unmix", -"unmixed", -"unmodel", -"unmoist", -"unmold", -"unmoldy", -"unmoor", -"unmoral", -"unmount", -"unmoved", -"unmowed", -"unmown", -"unmuddy", -"unmuted", -"unnail", -"unnaked", -"unname", -"unnamed", -"unneat", -"unneedy", -"unnegro", -"unnerve", -"unnest", -"unneth", -"unnethe", -"unnew", -"unnewly", -"unnice", -"unnigh", -"unnoble", -"unnobly", -"unnose", -"unnosed", -"unnoted", -"unnovel", -"unoared", -"unobese", -"unode", -"unoften", -"unogled", -"unoil", -"unoiled", -"unoily", -"unold", -"unoped", -"unopen", -"unorbed", -"unorder", -"unorn", -"unornly", -"unovert", -"unowed", -"unowing", -"unown", -"unowned", -"unpaced", -"unpack", -"unpagan", -"unpaged", -"unpaid", -"unpaint", -"unpale", -"unpaled", -"unpanel", -"unpapal", -"unpaper", -"unparch", -"unpared", -"unpark", -"unparty", -"unpass", -"unpaste", -"unpave", -"unpaved", -"unpawed", -"unpawn", -"unpeace", -"unpeel", -"unpeg", -"unpen", -"unpenal", -"unpent", -"unperch", -"unpetal", -"unpick", -"unpiece", -"unpiety", -"unpile", -"unpiled", -"unpin", -"unpious", -"unpiped", -"unplace", -"unplaid", -"unplain", -"unplait", -"unplan", -"unplank", -"unplant", -"unplat", -"unpleat", -"unplied", -"unplow", -"unplug", -"unplumb", -"unplume", -"unplump", -"unpoise", -"unpoled", -"unpope", -"unposed", -"unpot", -"unpower", -"unpray", -"unprim", -"unprime", -"unprint", -"unprop", -"unproud", -"unpure", -"unpurse", -"unput", -"unqueen", -"unquick", -"unquiet", -"unquit", -"unquote", -"unraced", -"unrack", -"unrainy", -"unrake", -"unraked", -"unram", -"unrank", -"unraped", -"unrare", -"unrash", -"unrated", -"unravel", -"unray", -"unrayed", -"unrazed", -"unread", -"unready", -"unreal", -"unreave", -"unrebel", -"unred", -"unreel", -"unreeve", -"unregal", -"unrein", -"unrent", -"unrest", -"unresty", -"unrhyme", -"unrich", -"unricht", -"unrid", -"unride", -"unrife", -"unrig", -"unright", -"unrigid", -"unrind", -"unring", -"unrip", -"unripe", -"unriped", -"unrisen", -"unrisky", -"unrived", -"unriven", -"unrivet", -"unroast", -"unrobe", -"unrobed", -"unroll", -"unroof", -"unroomy", -"unroost", -"unroot", -"unrope", -"unroped", -"unrosed", -"unroted", -"unrough", -"unround", -"unrove", -"unroved", -"unrow", -"unrowed", -"unroyal", -"unrule", -"unruled", -"unruly", -"unrun", -"unrung", -"unrural", -"unrust", -"unruth", -"unsack", -"unsad", -"unsafe", -"unsage", -"unsaid", -"unsaint", -"unsalt", -"unsane", -"unsappy", -"unsash", -"unsated", -"unsatin", -"unsaved", -"unsawed", -"unsawn", -"unsay", -"unscale", -"unscaly", -"unscarb", -"unscent", -"unscrew", -"unseal", -"unseam", -"unseat", -"unsee", -"unseen", -"unself", -"unsense", -"unsent", -"unset", -"unsew", -"unsewed", -"unsewn", -"unsex", -"unsexed", -"unshade", -"unshady", -"unshape", -"unsharp", -"unshawl", -"unsheaf", -"unshed", -"unsheet", -"unshell", -"unship", -"unshod", -"unshoe", -"unshoed", -"unshop", -"unshore", -"unshorn", -"unshort", -"unshot", -"unshown", -"unshowy", -"unshrew", -"unshut", -"unshy", -"unshyly", -"unsick", -"unsided", -"unsiege", -"unsight", -"unsilly", -"unsin", -"unsinew", -"unsing", -"unsized", -"unskin", -"unslack", -"unslain", -"unslate", -"unslave", -"unsleek", -"unslept", -"unsling", -"unslip", -"unslit", -"unslot", -"unslow", -"unslung", -"unsly", -"unsmart", -"unsmoky", -"unsmote", -"unsnaky", -"unsnap", -"unsnare", -"unsnarl", -"unsneck", -"unsnib", -"unsnow", -"unsober", -"unsoft", -"unsoggy", -"unsoil", -"unsolar", -"unsold", -"unsole", -"unsoled", -"unsolid", -"unsome", -"unson", -"unsonsy", -"unsooty", -"unsore", -"unsorry", -"unsort", -"unsoul", -"unsound", -"unsour", -"unsowed", -"unsown", -"unspan", -"unspar", -"unspeak", -"unsped", -"unspeed", -"unspell", -"unspelt", -"unspent", -"unspicy", -"unspied", -"unspike", -"unspin", -"unspit", -"unsplit", -"unspoil", -"unspot", -"unspun", -"unstack", -"unstagy", -"unstaid", -"unstain", -"unstar", -"unstate", -"unsteck", -"unsteel", -"unsteep", -"unstep", -"unstern", -"unstick", -"unstill", -"unsting", -"unstock", -"unstoic", -"unstone", -"unstony", -"unstop", -"unstore", -"unstout", -"unstow", -"unstrap", -"unstrip", -"unstuck", -"unstuff", -"unstung", -"unsty", -"unsued", -"unsuit", -"unsulky", -"unsun", -"unsung", -"unsunk", -"unsunny", -"unsure", -"unswear", -"unsweat", -"unsweet", -"unswell", -"unswept", -"unswing", -"unsworn", -"unswung", -"untack", -"untaint", -"untaken", -"untall", -"untame", -"untamed", -"untap", -"untaped", -"untar", -"untaste", -"untasty", -"untaut", -"untawed", -"untax", -"untaxed", -"unteach", -"unteam", -"unteem", -"untell", -"untense", -"untent", -"untenty", -"untewed", -"unthank", -"unthaw", -"unthick", -"unthink", -"unthorn", -"unthrid", -"unthrob", -"untidal", -"untidy", -"untie", -"untied", -"untight", -"until", -"untile", -"untiled", -"untill", -"untilt", -"untimed", -"untin", -"untinct", -"untine", -"untipt", -"untire", -"untired", -"unto", -"untold", -"untomb", -"untone", -"untoned", -"untooth", -"untop", -"untorn", -"untouch", -"untough", -"untown", -"untrace", -"untrain", -"untread", -"untreed", -"untress", -"untried", -"untrig", -"untrill", -"untrim", -"untripe", -"untrite", -"untrod", -"untruck", -"untrue", -"untruly", -"untruss", -"untrust", -"untruth", -"untuck", -"untumid", -"untune", -"untuned", -"unturf", -"unturn", -"untwine", -"untwirl", -"untwist", -"untying", -"untz", -"unugly", -"unultra", -"unupset", -"unurban", -"unurged", -"unurn", -"unurned", -"unuse", -"unused", -"unusual", -"unvain", -"unvalid", -"unvalue", -"unveil", -"unvenom", -"unvest", -"unvexed", -"unvicar", -"unvisor", -"unvital", -"unvivid", -"unvocal", -"unvoice", -"unvote", -"unvoted", -"unvowed", -"unwaded", -"unwaged", -"unwaked", -"unwall", -"unwan", -"unware", -"unwarm", -"unwarn", -"unwarp", -"unwary", -"unwater", -"unwaved", -"unwax", -"unwaxed", -"unwayed", -"unweal", -"unweary", -"unweave", -"unweb", -"unwed", -"unwedge", -"unweel", -"unweft", -"unweld", -"unwell", -"unwept", -"unwet", -"unwheel", -"unwhig", -"unwhip", -"unwhite", -"unwield", -"unwifed", -"unwig", -"unwild", -"unwill", -"unwily", -"unwind", -"unwindy", -"unwiped", -"unwire", -"unwired", -"unwise", -"unwish", -"unwist", -"unwitch", -"unwitty", -"unwive", -"unwived", -"unwoful", -"unwoman", -"unwomb", -"unwon", -"unwooed", -"unwoof", -"unwooly", -"unwordy", -"unwork", -"unworld", -"unwormy", -"unworn", -"unworth", -"unwound", -"unwoven", -"unwrap", -"unwrit", -"unwrite", -"unwrung", -"unyoke", -"unyoked", -"unyoung", -"unze", -"unzen", -"unzone", -"unzoned", -"up", -"upaisle", -"upalley", -"upalong", -"uparch", -"uparise", -"uparm", -"uparna", -"upas", -"upattic", -"upbank", -"upbar", -"upbay", -"upbear", -"upbeat", -"upbelch", -"upbelt", -"upbend", -"upbid", -"upbind", -"upblast", -"upblaze", -"upblow", -"upboil", -"upbolt", -"upboost", -"upborne", -"upbotch", -"upbound", -"upbrace", -"upbraid", -"upbray", -"upbreak", -"upbred", -"upbreed", -"upbrim", -"upbring", -"upbrook", -"upbrow", -"upbuild", -"upbuoy", -"upburn", -"upburst", -"upbuy", -"upcall", -"upcanal", -"upcarry", -"upcast", -"upcatch", -"upchoke", -"upchuck", -"upcity", -"upclimb", -"upclose", -"upcoast", -"upcock", -"upcoil", -"upcome", -"upcover", -"upcrane", -"upcrawl", -"upcreek", -"upcreep", -"upcrop", -"upcrowd", -"upcry", -"upcurl", -"upcurve", -"upcut", -"updart", -"update", -"updeck", -"updelve", -"updive", -"updo", -"updome", -"updraft", -"updrag", -"updraw", -"updrink", -"updry", -"upeat", -"upend", -"upeygan", -"upfeed", -"upfield", -"upfill", -"upflame", -"upflare", -"upflash", -"upflee", -"upfling", -"upfloat", -"upflood", -"upflow", -"upflung", -"upfly", -"upfold", -"upframe", -"upfurl", -"upgale", -"upgang", -"upgape", -"upgaze", -"upget", -"upgird", -"upgirt", -"upgive", -"upglean", -"upglide", -"upgo", -"upgorge", -"upgrade", -"upgrave", -"upgrow", -"upgully", -"upgush", -"uphand", -"uphang", -"uphasp", -"upheal", -"upheap", -"upheave", -"upheld", -"uphelm", -"uphelya", -"upher", -"uphill", -"uphoard", -"uphoist", -"uphold", -"uphung", -"uphurl", -"upjerk", -"upjet", -"upkeep", -"upknell", -"upknit", -"upla", -"uplaid", -"uplake", -"upland", -"uplane", -"uplay", -"uplead", -"upleap", -"upleg", -"uplick", -"uplift", -"uplight", -"uplimb", -"upline", -"uplock", -"uplong", -"uplook", -"uploom", -"uploop", -"uplying", -"upmast", -"upmix", -"upmost", -"upmount", -"upmove", -"upness", -"upo", -"upon", -"uppard", -"uppent", -"upper", -"upperch", -"upperer", -"uppers", -"uppile", -"upping", -"uppish", -"uppity", -"upplow", -"uppluck", -"uppoint", -"uppoise", -"uppop", -"uppour", -"uppowoc", -"upprick", -"upprop", -"uppuff", -"uppull", -"uppush", -"upraise", -"upreach", -"uprear", -"uprein", -"uprend", -"uprest", -"uprid", -"upridge", -"upright", -"uprip", -"uprisal", -"uprise", -"uprisen", -"upriser", -"uprist", -"uprive", -"upriver", -"uproad", -"uproar", -"uproom", -"uproot", -"uprose", -"uprouse", -"uproute", -"uprun", -"uprush", -"upscale", -"upscrew", -"upseal", -"upseek", -"upseize", -"upsend", -"upset", -"upsey", -"upshaft", -"upshear", -"upshoot", -"upshore", -"upshot", -"upshove", -"upshut", -"upside", -"upsides", -"upsilon", -"upsit", -"upslant", -"upslip", -"upslope", -"upsmite", -"upsoak", -"upsoar", -"upsolve", -"upspeak", -"upspear", -"upspeed", -"upspew", -"upspin", -"upspire", -"upspout", -"upspurt", -"upstaff", -"upstage", -"upstair", -"upstamp", -"upstand", -"upstare", -"upstart", -"upstate", -"upstay", -"upsteal", -"upsteam", -"upstem", -"upstep", -"upstick", -"upstir", -"upsuck", -"upsun", -"upsup", -"upsurge", -"upswarm", -"upsway", -"upsweep", -"upswell", -"upswing", -"uptable", -"uptake", -"uptaker", -"uptear", -"uptend", -"upthrow", -"uptide", -"uptie", -"uptill", -"uptilt", -"uptorn", -"uptoss", -"uptower", -"uptown", -"uptrace", -"uptrack", -"uptrail", -"uptrain", -"uptree", -"uptrend", -"uptrill", -"uptrunk", -"uptruss", -"uptube", -"uptuck", -"upturn", -"uptwist", -"upupoid", -"upvomit", -"upwaft", -"upwall", -"upward", -"upwards", -"upwarp", -"upwax", -"upway", -"upways", -"upwell", -"upwent", -"upwheel", -"upwhelm", -"upwhir", -"upwhirl", -"upwind", -"upwith", -"upwork", -"upwound", -"upwrap", -"upwring", -"upyard", -"upyoke", -"ur", -"ura", -"urachal", -"urachus", -"uracil", -"uraemic", -"uraeus", -"ural", -"urali", -"uraline", -"uralite", -"uralium", -"uramido", -"uramil", -"uramino", -"uran", -"uranate", -"uranic", -"uraniid", -"uranin", -"uranine", -"uranion", -"uranism", -"uranist", -"uranite", -"uranium", -"uranous", -"uranyl", -"urao", -"urare", -"urari", -"urase", -"urate", -"uratic", -"uratoma", -"urazine", -"urazole", -"urban", -"urbane", -"urbian", -"urbic", -"urbify", -"urceole", -"urceoli", -"urceus", -"urchin", -"urd", -"urde", -"urdee", -"ure", -"urea", -"ureal", -"urease", -"uredema", -"uredine", -"uredo", -"ureic", -"ureid", -"ureide", -"ureido", -"uremia", -"uremic", -"urent", -"uresis", -"uretal", -"ureter", -"urethan", -"urethra", -"uretic", -"urf", -"urge", -"urgence", -"urgency", -"urgent", -"urger", -"urging", -"urheen", -"urial", -"uric", -"urinal", -"urinant", -"urinary", -"urinate", -"urine", -"urinose", -"urinous", -"urite", -"urlar", -"urled", -"urling", -"urluch", -"urman", -"urn", -"urna", -"urnae", -"urnal", -"urnful", -"urning", -"urnism", -"urnlike", -"urocele", -"urocyst", -"urodele", -"urogram", -"urohyal", -"urolith", -"urology", -"uromere", -"uronic", -"uropod", -"urosis", -"urosome", -"urostea", -"urotoxy", -"uroxin", -"ursal", -"ursine", -"ursoid", -"ursolic", -"urson", -"ursone", -"ursuk", -"urtica", -"urtite", -"urubu", -"urucu", -"urucuri", -"uruisg", -"urunday", -"urus", -"urushi", -"urushic", -"urva", -"us", -"usable", -"usage", -"usager", -"usance", -"usar", -"usara", -"usaron", -"usation", -"use", -"used", -"usedly", -"usednt", -"usee", -"useful", -"usehold", -"useless", -"usent", -"user", -"ush", -"ushabti", -"usher", -"usherer", -"usings", -"usitate", -"usnea", -"usneoid", -"usnic", -"usninic", -"usque", -"usself", -"ussels", -"ust", -"uster", -"ustion", -"usual", -"usually", -"usuary", -"usucapt", -"usure", -"usurer", -"usuress", -"usurp", -"usurper", -"usurpor", -"usury", -"usward", -"uswards", -"ut", -"uta", -"utahite", -"utai", -"utas", -"utch", -"utchy", -"utees", -"utensil", -"uteri", -"uterine", -"uterus", -"utick", -"utile", -"utility", -"utilize", -"utinam", -"utmost", -"utopia", -"utopian", -"utopism", -"utopist", -"utricle", -"utricul", -"utrubi", -"utrum", -"utsuk", -"utter", -"utterer", -"utterly", -"utu", -"utum", -"uva", -"uval", -"uvalha", -"uvanite", -"uvate", -"uvea", -"uveal", -"uveitic", -"uveitis", -"uveous", -"uvic", -"uvid", -"uviol", -"uvitic", -"uvito", -"uvrou", -"uvula", -"uvulae", -"uvular", -"uvver", -"uxorial", -"uzan", -"uzara", -"uzarin", -"uzaron", -"v", -"vaagmer", -"vaalite", -"vacancy", -"vacant", -"vacate", -"vacatur", -"vaccary", -"vaccina", -"vaccine", -"vache", -"vacoa", -"vacona", -"vacoua", -"vacouf", -"vacual", -"vacuate", -"vacuefy", -"vacuist", -"vacuity", -"vacuole", -"vacuome", -"vacuous", -"vacuum", -"vacuuma", -"vade", -"vadium", -"vadose", -"vady", -"vag", -"vagal", -"vagary", -"vagas", -"vage", -"vagile", -"vagina", -"vaginal", -"vagitus", -"vagrant", -"vagrate", -"vagrom", -"vague", -"vaguely", -"vaguish", -"vaguity", -"vagus", -"vahine", -"vail", -"vain", -"vainful", -"vainly", -"vair", -"vairagi", -"vaire", -"vairy", -"vaivode", -"vajra", -"vakass", -"vakia", -"vakil", -"valance", -"vale", -"valence", -"valency", -"valent", -"valeral", -"valeric", -"valerin", -"valeryl", -"valet", -"valeta", -"valetry", -"valeur", -"valgoid", -"valgus", -"valhall", -"vali", -"valiant", -"valid", -"validly", -"valine", -"valise", -"vall", -"vallar", -"vallary", -"vallate", -"valley", -"vallis", -"vallum", -"valonia", -"valor", -"valse", -"valsoid", -"valuate", -"value", -"valued", -"valuer", -"valuta", -"valva", -"valval", -"valvate", -"valve", -"valved", -"valvula", -"valvule", -"valyl", -"vamfont", -"vamoose", -"vamp", -"vamped", -"vamper", -"vampire", -"van", -"vanadic", -"vanadyl", -"vane", -"vaned", -"vanfoss", -"vang", -"vangee", -"vangeli", -"vanglo", -"vanilla", -"vanille", -"vanish", -"vanity", -"vanman", -"vanmost", -"vanner", -"vannet", -"vansire", -"vantage", -"vanward", -"vapid", -"vapidly", -"vapor", -"vapored", -"vaporer", -"vapory", -"vara", -"varahan", -"varan", -"varanid", -"vardy", -"vare", -"varec", -"vareuse", -"vari", -"variant", -"variate", -"varical", -"varices", -"varied", -"varier", -"variety", -"variola", -"variole", -"various", -"varisse", -"varix", -"varlet", -"varment", -"varna", -"varnish", -"varsha", -"varsity", -"varus", -"varve", -"varved", -"vary", -"vas", -"vasa", -"vasal", -"vase", -"vaseful", -"vaselet", -"vassal", -"vast", -"vastate", -"vastily", -"vastity", -"vastly", -"vasty", -"vasu", -"vat", -"vatful", -"vatic", -"vatman", -"vatter", -"vau", -"vaudy", -"vault", -"vaulted", -"vaulter", -"vaulty", -"vaunt", -"vaunted", -"vaunter", -"vaunty", -"vauxite", -"vavasor", -"vaward", -"veal", -"vealer", -"vealy", -"vection", -"vectis", -"vector", -"vecture", -"vedana", -"vedette", -"vedika", -"vedro", -"veduis", -"vee", -"veen", -"veep", -"veer", -"veery", -"vegetal", -"vegete", -"vehicle", -"vei", -"veigle", -"veil", -"veiled", -"veiler", -"veiling", -"veily", -"vein", -"veinage", -"veinal", -"veined", -"veiner", -"veinery", -"veining", -"veinlet", -"veinous", -"veinule", -"veiny", -"vejoces", -"vela", -"velal", -"velamen", -"velar", -"velaric", -"velary", -"velate", -"velated", -"veldman", -"veldt", -"velic", -"veliger", -"vell", -"vellala", -"velleda", -"vellon", -"vellum", -"vellumy", -"velo", -"velours", -"velte", -"velum", -"velumen", -"velure", -"velvet", -"velvety", -"venada", -"venal", -"venally", -"venatic", -"venator", -"vencola", -"vend", -"vendace", -"vendee", -"vender", -"vending", -"vendor", -"vendue", -"veneer", -"venene", -"veneral", -"venerer", -"venery", -"venesia", -"venger", -"venial", -"venie", -"venin", -"venison", -"vennel", -"venner", -"venom", -"venomed", -"venomer", -"venomly", -"venomy", -"venosal", -"venose", -"venous", -"vent", -"ventage", -"ventail", -"venter", -"ventil", -"ventose", -"ventrad", -"ventral", -"ventric", -"venture", -"venue", -"venula", -"venular", -"venule", -"venust", -"vera", -"veranda", -"verb", -"verbal", -"verbate", -"verbena", -"verbene", -"verbid", -"verbify", -"verbile", -"verbose", -"verbous", -"verby", -"verchok", -"verd", -"verdant", -"verdea", -"verdet", -"verdict", -"verdin", -"verdoy", -"verdun", -"verdure", -"verek", -"verge", -"vergent", -"verger", -"vergery", -"vergi", -"verglas", -"veri", -"veridic", -"verify", -"verily", -"verine", -"verism", -"verist", -"verite", -"verity", -"vermeil", -"vermian", -"vermin", -"verminy", -"vermis", -"vermix", -"vernal", -"vernant", -"vernier", -"vernile", -"vernin", -"vernine", -"verre", -"verrel", -"verruca", -"verruga", -"versal", -"versant", -"versate", -"verse", -"versed", -"verser", -"verset", -"versify", -"versine", -"version", -"verso", -"versor", -"verst", -"versta", -"versual", -"versus", -"vert", -"vertex", -"vertigo", -"veruled", -"vervain", -"verve", -"vervel", -"vervet", -"very", -"vesania", -"vesanic", -"vesbite", -"vesicae", -"vesical", -"vesicle", -"veskit", -"vespal", -"vesper", -"vespers", -"vespery", -"vespid", -"vespine", -"vespoid", -"vessel", -"vest", -"vestal", -"vestee", -"vester", -"vestige", -"vesting", -"vestlet", -"vestral", -"vestry", -"vesture", -"vet", -"veta", -"vetanda", -"vetch", -"vetchy", -"veteran", -"vetiver", -"veto", -"vetoer", -"vetoism", -"vetoist", -"vetust", -"vetusty", -"veuve", -"vex", -"vexable", -"vexed", -"vexedly", -"vexer", -"vexful", -"vexil", -"vext", -"via", -"viable", -"viaduct", -"viagram", -"viajaca", -"vial", -"vialful", -"viand", -"viander", -"viatic", -"viatica", -"viator", -"vibex", -"vibgyor", -"vibix", -"vibrant", -"vibrate", -"vibrato", -"vibrion", -"vicar", -"vicarly", -"vice", -"viceroy", -"vicety", -"vicilin", -"vicinal", -"vicine", -"vicious", -"vicoite", -"victim", -"victor", -"victory", -"victrix", -"victual", -"vicuna", -"viddui", -"video", -"vidette", -"vidonia", -"vidry", -"viduage", -"vidual", -"viduate", -"viduine", -"viduity", -"viduous", -"vidya", -"vie", -"vielle", -"vier", -"viertel", -"view", -"viewer", -"viewly", -"viewy", -"vifda", -"viga", -"vigia", -"vigil", -"vignin", -"vigonia", -"vigor", -"vihara", -"vihuela", -"vijao", -"viking", -"vila", -"vilayet", -"vile", -"vilely", -"vilify", -"vility", -"vill", -"villa", -"village", -"villain", -"villar", -"villate", -"ville", -"villein", -"villoid", -"villose", -"villous", -"villus", -"vim", -"vimana", -"vimen", -"vimful", -"viminal", -"vina", -"vinage", -"vinal", -"vinasse", -"vinata", -"vincent", -"vindex", -"vine", -"vinea", -"vineal", -"vined", -"vinegar", -"vineity", -"vinelet", -"viner", -"vinery", -"vinic", -"vinny", -"vino", -"vinose", -"vinous", -"vint", -"vinta", -"vintage", -"vintem", -"vintner", -"vintry", -"viny", -"vinyl", -"vinylic", -"viol", -"viola", -"violal", -"violate", -"violent", -"violer", -"violet", -"violety", -"violin", -"violina", -"violine", -"violist", -"violon", -"violone", -"viper", -"viperan", -"viperid", -"vipery", -"viqueen", -"viragin", -"virago", -"viral", -"vire", -"virelay", -"viremia", -"viremic", -"virent", -"vireo", -"virga", -"virgal", -"virgate", -"virgin", -"virgula", -"virgule", -"virial", -"virid", -"virific", -"virify", -"virile", -"virl", -"virole", -"viroled", -"viron", -"virose", -"virosis", -"virous", -"virtu", -"virtual", -"virtue", -"virtued", -"viruela", -"virus", -"vis", -"visa", -"visage", -"visaged", -"visarga", -"viscera", -"viscid", -"viscin", -"viscose", -"viscous", -"viscus", -"vise", -"viseman", -"visible", -"visibly", -"visie", -"visile", -"vision", -"visit", -"visita", -"visite", -"visitee", -"visiter", -"visitor", -"visive", -"visne", -"vison", -"visor", -"vista", -"vistaed", -"vistal", -"visto", -"visual", -"vita", -"vital", -"vitalic", -"vitally", -"vitals", -"vitamer", -"vitamin", -"vitasti", -"vitiate", -"vitium", -"vitrage", -"vitrail", -"vitrain", -"vitraux", -"vitreal", -"vitrean", -"vitreum", -"vitric", -"vitrics", -"vitrify", -"vitrine", -"vitriol", -"vitrite", -"vitrous", -"vitta", -"vittate", -"vitular", -"viuva", -"viva", -"vivary", -"vivax", -"vive", -"vively", -"vivency", -"viver", -"vivers", -"vives", -"vivid", -"vividly", -"vivific", -"vivify", -"vixen", -"vixenly", -"vizard", -"vizier", -"vlei", -"voar", -"vocable", -"vocably", -"vocal", -"vocalic", -"vocally", -"vocate", -"vocular", -"vocule", -"vodka", -"voe", -"voet", -"voeten", -"vog", -"voglite", -"vogue", -"voguey", -"voguish", -"voice", -"voiced", -"voicer", -"voicing", -"void", -"voided", -"voidee", -"voider", -"voiding", -"voidly", -"voile", -"voivode", -"vol", -"volable", -"volage", -"volant", -"volar", -"volata", -"volatic", -"volcan", -"volcano", -"vole", -"volency", -"volent", -"volery", -"volet", -"volley", -"volost", -"volt", -"voltage", -"voltaic", -"voltize", -"voluble", -"volubly", -"volume", -"volumed", -"volupt", -"volupty", -"voluta", -"volute", -"voluted", -"volutin", -"volva", -"volvate", -"volvent", -"vomer", -"vomica", -"vomit", -"vomiter", -"vomito", -"vomitus", -"voodoo", -"vorago", -"vorant", -"vorhand", -"vorpal", -"vortex", -"vota", -"votable", -"votal", -"votally", -"votary", -"vote", -"voteen", -"voter", -"voting", -"votive", -"votress", -"vouch", -"vouchee", -"voucher", -"vouge", -"vow", -"vowed", -"vowel", -"vowely", -"vower", -"vowess", -"vowless", -"voyage", -"voyager", -"voyance", -"voyeur", -"vraic", -"vrbaite", -"vriddhi", -"vrother", -"vug", -"vuggy", -"vulgar", -"vulgare", -"vulgate", -"vulgus", -"vuln", -"vulnose", -"vulpic", -"vulpine", -"vulture", -"vulturn", -"vulva", -"vulval", -"vulvar", -"vulvate", -"vum", -"vying", -"vyingly", -"w", -"wa", -"waag", -"waapa", -"waar", -"wab", -"wabber", -"wabble", -"wabbly", -"wabby", -"wabe", -"wabeno", -"wabster", -"wacago", -"wace", -"wachna", -"wack", -"wacke", -"wacken", -"wacker", -"wacky", -"wad", -"waddent", -"wadder", -"wadding", -"waddler", -"waddly", -"waddy", -"wade", -"wader", -"wadi", -"wading", -"wadlike", -"wadmal", -"wadmeal", -"wadna", -"wadset", -"wae", -"waeg", -"waer", -"waesome", -"waesuck", -"wafer", -"waferer", -"wafery", -"waff", -"waffle", -"waffly", -"waft", -"waftage", -"wafter", -"wafture", -"wafty", -"wag", -"wagaun", -"wage", -"waged", -"wagedom", -"wager", -"wagerer", -"wages", -"waggel", -"wagger", -"waggery", -"waggie", -"waggish", -"waggle", -"waggly", -"waggy", -"waglike", -"wagling", -"wagon", -"wagoner", -"wagonry", -"wagsome", -"wagtail", -"wagwag", -"wagwit", -"wah", -"wahahe", -"wahine", -"wahoo", -"waiata", -"waif", -"waik", -"waikly", -"wail", -"wailer", -"wailful", -"waily", -"wain", -"wainage", -"wainer", -"wainful", -"wainman", -"waipiro", -"wairch", -"waird", -"wairepo", -"wairsh", -"waise", -"waist", -"waisted", -"waister", -"wait", -"waiter", -"waiting", -"waive", -"waiver", -"waivery", -"waivod", -"waiwode", -"wajang", -"waka", -"wakan", -"wake", -"wakeel", -"wakeful", -"waken", -"wakener", -"waker", -"wakes", -"wakf", -"wakif", -"wakiki", -"waking", -"wakiup", -"wakken", -"wakon", -"wakonda", -"waky", -"walahee", -"wale", -"waled", -"waler", -"wali", -"waling", -"walk", -"walker", -"walking", -"walkist", -"walkout", -"walkway", -"wall", -"wallaba", -"wallaby", -"wallah", -"walled", -"waller", -"wallet", -"walleye", -"wallful", -"walling", -"wallise", -"wallman", -"walloon", -"wallop", -"wallow", -"wally", -"walnut", -"walrus", -"walsh", -"walt", -"walter", -"walth", -"waltz", -"waltzer", -"wamara", -"wambais", -"wamble", -"wambly", -"wame", -"wamefou", -"wamel", -"wamp", -"wampee", -"wample", -"wampum", -"wampus", -"wamus", -"wan", -"wand", -"wander", -"wandery", -"wandle", -"wandoo", -"wandy", -"wane", -"waned", -"wang", -"wanga", -"wangala", -"wangan", -"wanghee", -"wangle", -"wangler", -"wanhope", -"wanhorn", -"wanigan", -"waning", -"wankle", -"wankly", -"wanle", -"wanly", -"wanner", -"wanness", -"wannish", -"wanny", -"wanrufe", -"want", -"wantage", -"wanter", -"wantful", -"wanting", -"wanton", -"wantwit", -"wanty", -"wany", -"wap", -"wapacut", -"wapatoo", -"wapiti", -"wapp", -"wapper", -"wapping", -"war", -"warabi", -"waratah", -"warble", -"warbled", -"warbler", -"warblet", -"warbly", -"warch", -"ward", -"wardage", -"warday", -"warded", -"warden", -"warder", -"warding", -"wardite", -"wardman", -"ware", -"warehou", -"wareman", -"warf", -"warfare", -"warful", -"warily", -"warish", -"warison", -"wark", -"warl", -"warless", -"warlike", -"warlock", -"warluck", -"warly", -"warm", -"warman", -"warmed", -"warmer", -"warmful", -"warming", -"warmish", -"warmly", -"warmth", -"warmus", -"warn", -"warnel", -"warner", -"warning", -"warnish", -"warnoth", -"warnt", -"warp", -"warpage", -"warped", -"warper", -"warping", -"warple", -"warran", -"warrand", -"warrant", -"warree", -"warren", -"warrer", -"warrin", -"warrior", -"warrok", -"warsaw", -"warse", -"warsel", -"warship", -"warsle", -"warsler", -"warst", -"wart", -"warted", -"wartern", -"warth", -"wartime", -"wartlet", -"warty", -"warve", -"warwolf", -"warworn", -"wary", -"was", -"wasabi", -"wase", -"wasel", -"wash", -"washday", -"washed", -"washen", -"washer", -"washery", -"washin", -"washing", -"washman", -"washoff", -"washout", -"washpot", -"washrag", -"washtub", -"washway", -"washy", -"wasnt", -"wasp", -"waspen", -"waspily", -"waspish", -"waspy", -"wassail", -"wassie", -"wast", -"wastage", -"waste", -"wasted", -"wastel", -"waster", -"wasting", -"wastrel", -"wasty", -"wat", -"watap", -"watch", -"watched", -"watcher", -"water", -"watered", -"waterer", -"waterie", -"watery", -"wath", -"watt", -"wattage", -"wattape", -"wattle", -"wattled", -"wattman", -"wauble", -"wauch", -"wauchle", -"waucht", -"wauf", -"waugh", -"waughy", -"wauken", -"waukit", -"waul", -"waumle", -"wauner", -"wauns", -"waup", -"waur", -"wauve", -"wavable", -"wavably", -"wave", -"waved", -"wavelet", -"waver", -"waverer", -"wavery", -"waveson", -"wavey", -"wavicle", -"wavily", -"waving", -"wavy", -"waw", -"wawa", -"wawah", -"wax", -"waxbill", -"waxbird", -"waxbush", -"waxen", -"waxer", -"waxily", -"waxing", -"waxlike", -"waxman", -"waxweed", -"waxwing", -"waxwork", -"waxy", -"way", -"wayaka", -"wayang", -"wayback", -"waybill", -"waybird", -"waybook", -"waybung", -"wayfare", -"waygang", -"waygate", -"waygone", -"waying", -"waylaid", -"waylay", -"wayless", -"wayman", -"waymark", -"waymate", -"waypost", -"ways", -"wayside", -"wayward", -"waywode", -"wayworn", -"waywort", -"we", -"weak", -"weaken", -"weakish", -"weakly", -"weaky", -"weal", -"weald", -"wealth", -"wealthy", -"weam", -"wean", -"weanel", -"weaner", -"weanyer", -"weapon", -"wear", -"wearer", -"wearied", -"wearier", -"wearily", -"wearing", -"wearish", -"weary", -"weasand", -"weasel", -"weaser", -"weason", -"weather", -"weave", -"weaved", -"weaver", -"weaving", -"weazen", -"weazeny", -"web", -"webbed", -"webber", -"webbing", -"webby", -"weber", -"webeye", -"webfoot", -"webless", -"weblike", -"webster", -"webwork", -"webworm", -"wecht", -"wed", -"wedana", -"wedbed", -"wedded", -"wedder", -"wedding", -"wede", -"wedge", -"wedged", -"wedger", -"wedging", -"wedgy", -"wedlock", -"wedset", -"wee", -"weeble", -"weed", -"weeda", -"weedage", -"weeded", -"weeder", -"weedery", -"weedful", -"weedish", -"weedow", -"weedy", -"week", -"weekday", -"weekend", -"weekly", -"weekwam", -"weel", -"weemen", -"ween", -"weeness", -"weening", -"weenong", -"weeny", -"weep", -"weeper", -"weepful", -"weeping", -"weeps", -"weepy", -"weesh", -"weeshy", -"weet", -"weever", -"weevil", -"weevily", -"weewow", -"weeze", -"weft", -"weftage", -"wefted", -"wefty", -"weigh", -"weighed", -"weigher", -"weighin", -"weight", -"weighty", -"weir", -"weird", -"weirdly", -"weiring", -"weism", -"wejack", -"weka", -"wekau", -"wekeen", -"weki", -"welcome", -"weld", -"welder", -"welding", -"weldor", -"welfare", -"welk", -"welkin", -"well", -"wellat", -"welling", -"wellish", -"wellman", -"welly", -"wels", -"welsh", -"welsher", -"welsium", -"welt", -"welted", -"welter", -"welting", -"wem", -"wemless", -"wen", -"wench", -"wencher", -"wend", -"wende", -"wene", -"wennish", -"wenny", -"went", -"wenzel", -"wept", -"wer", -"were", -"werefox", -"werent", -"werf", -"wergil", -"weri", -"wert", -"wervel", -"wese", -"weskit", -"west", -"weste", -"wester", -"western", -"westing", -"westy", -"wet", -"weta", -"wetback", -"wetbird", -"wetched", -"wetchet", -"wether", -"wetly", -"wetness", -"wetted", -"wetter", -"wetting", -"wettish", -"weve", -"wevet", -"wey", -"wha", -"whabby", -"whack", -"whacker", -"whacky", -"whale", -"whaler", -"whalery", -"whaling", -"whalish", -"whally", -"whalm", -"whalp", -"whaly", -"wham", -"whamble", -"whame", -"whammle", -"whamp", -"whampee", -"whample", -"whan", -"whand", -"whang", -"whangam", -"whangee", -"whank", -"whap", -"whappet", -"whapuka", -"whapuku", -"whar", -"whare", -"whareer", -"wharf", -"wharl", -"wharp", -"wharry", -"whart", -"wharve", -"whase", -"whasle", -"what", -"whata", -"whatkin", -"whatna", -"whatnot", -"whats", -"whatso", -"whatten", -"whau", -"whauk", -"whaup", -"whaur", -"whauve", -"wheal", -"whealy", -"wheam", -"wheat", -"wheaten", -"wheaty", -"whedder", -"whee", -"wheedle", -"wheel", -"wheeled", -"wheeler", -"wheely", -"wheem", -"wheen", -"wheenge", -"wheep", -"wheeple", -"wheer", -"wheesht", -"wheetle", -"wheeze", -"wheezer", -"wheezle", -"wheezy", -"wheft", -"whein", -"whekau", -"wheki", -"whelk", -"whelked", -"whelker", -"whelky", -"whelm", -"whelp", -"whelve", -"whemmel", -"when", -"whenas", -"whence", -"wheneer", -"whenso", -"where", -"whereas", -"whereat", -"whereby", -"whereer", -"wherein", -"whereof", -"whereon", -"whereso", -"whereto", -"whereup", -"wherret", -"wherrit", -"wherry", -"whet", -"whether", -"whetile", -"whetter", -"whew", -"whewer", -"whewl", -"whewt", -"whey", -"wheyey", -"wheyish", -"whiba", -"which", -"whick", -"whicken", -"whicker", -"whid", -"whidah", -"whidder", -"whiff", -"whiffer", -"whiffet", -"whiffle", -"whiffy", -"whift", -"whig", -"while", -"whileen", -"whilere", -"whiles", -"whilie", -"whilk", -"whill", -"whilly", -"whilock", -"whilom", -"whils", -"whilst", -"whilter", -"whim", -"whimble", -"whimmy", -"whimper", -"whimsey", -"whimsic", -"whin", -"whincow", -"whindle", -"whine", -"whiner", -"whing", -"whinge", -"whinger", -"whinnel", -"whinner", -"whinny", -"whiny", -"whip", -"whipcat", -"whipman", -"whippa", -"whipped", -"whipper", -"whippet", -"whippy", -"whipsaw", -"whipt", -"whir", -"whirken", -"whirl", -"whirled", -"whirler", -"whirley", -"whirly", -"whirret", -"whirrey", -"whirroo", -"whirry", -"whirtle", -"whish", -"whisk", -"whisker", -"whiskey", -"whisky", -"whisp", -"whisper", -"whissle", -"whist", -"whister", -"whistle", -"whistly", -"whit", -"white", -"whited", -"whitely", -"whiten", -"whites", -"whither", -"whiting", -"whitish", -"whitlow", -"whits", -"whittaw", -"whitten", -"whitter", -"whittle", -"whity", -"whiz", -"whizgig", -"whizzer", -"whizzle", -"who", -"whoa", -"whoever", -"whole", -"wholly", -"whom", -"whomble", -"whomso", -"whone", -"whoo", -"whoof", -"whoop", -"whoopee", -"whooper", -"whoops", -"whoosh", -"whop", -"whopper", -"whorage", -"whore", -"whorish", -"whorl", -"whorled", -"whorly", -"whort", -"whortle", -"whose", -"whosen", -"whud", -"whuff", -"whuffle", -"whulk", -"whulter", -"whummle", -"whun", -"whup", -"whush", -"whuskie", -"whussle", -"whute", -"whuther", -"whutter", -"whuz", -"why", -"whyever", -"whyfor", -"whyness", -"whyo", -"wi", -"wice", -"wicht", -"wichtje", -"wick", -"wicked", -"wicken", -"wicker", -"wicket", -"wicking", -"wickiup", -"wickup", -"wicky", -"wicopy", -"wid", -"widbin", -"widder", -"widdle", -"widdy", -"wide", -"widegab", -"widely", -"widen", -"widener", -"widgeon", -"widish", -"widow", -"widowed", -"widower", -"widowly", -"widowy", -"width", -"widu", -"wield", -"wielder", -"wieldy", -"wiener", -"wienie", -"wife", -"wifedom", -"wifeism", -"wifekin", -"wifelet", -"wifely", -"wifie", -"wifish", -"wifock", -"wig", -"wigan", -"wigdom", -"wigful", -"wigged", -"wiggen", -"wigger", -"wiggery", -"wigging", -"wiggish", -"wiggism", -"wiggle", -"wiggler", -"wiggly", -"wiggy", -"wight", -"wightly", -"wigless", -"wiglet", -"wiglike", -"wigtail", -"wigwag", -"wigwam", -"wiikite", -"wild", -"wildcat", -"wilded", -"wilder", -"wilding", -"wildish", -"wildly", -"wile", -"wileful", -"wilga", -"wilgers", -"wilily", -"wilk", -"wilkin", -"will", -"willawa", -"willed", -"willer", -"willet", -"willey", -"willful", -"willie", -"willier", -"willies", -"willing", -"willock", -"willow", -"willowy", -"willy", -"willyer", -"wilsome", -"wilt", -"wilter", -"wily", -"wim", -"wimble", -"wimbrel", -"wime", -"wimick", -"wimple", -"win", -"wince", -"wincer", -"wincey", -"winch", -"wincher", -"wincing", -"wind", -"windage", -"windbag", -"winddog", -"winded", -"winder", -"windigo", -"windily", -"winding", -"windle", -"windles", -"windlin", -"windock", -"windore", -"window", -"windowy", -"windrow", -"windup", -"windway", -"windy", -"wine", -"wined", -"winemay", -"winepot", -"winer", -"winery", -"winesop", -"winevat", -"winful", -"wing", -"wingcut", -"winged", -"winger", -"wingle", -"winglet", -"wingman", -"wingy", -"winish", -"wink", -"winkel", -"winker", -"winking", -"winkle", -"winklet", -"winly", -"winna", -"winnard", -"winnel", -"winner", -"winning", -"winnle", -"winnow", -"winrace", -"winrow", -"winsome", -"wint", -"winter", -"wintle", -"wintry", -"winy", -"winze", -"wipe", -"wiper", -"wippen", -"wips", -"wir", -"wirable", -"wirble", -"wird", -"wire", -"wirebar", -"wired", -"wireman", -"wirer", -"wireway", -"wirily", -"wiring", -"wirl", -"wirling", -"wirr", -"wirra", -"wirrah", -"wiry", -"wis", -"wisdom", -"wise", -"wisely", -"wiseman", -"wisen", -"wisent", -"wiser", -"wish", -"wisha", -"wished", -"wisher", -"wishful", -"wishing", -"wishly", -"wishmay", -"wisht", -"wisket", -"wisp", -"wispish", -"wispy", -"wiss", -"wisse", -"wissel", -"wist", -"wiste", -"wistful", -"wistit", -"wistiti", -"wit", -"witan", -"witch", -"witched", -"witchen", -"witchet", -"witchy", -"wite", -"witess", -"witful", -"with", -"withal", -"withe", -"withen", -"wither", -"withers", -"withery", -"within", -"without", -"withy", -"witjar", -"witless", -"witlet", -"witling", -"witloof", -"producer", -"witney", -"witship", -"wittal", -"witted", -"witter", -"wittily", -"witting", -"wittol", -"witty", -"witwall", -"wive", -"wiver", -"wivern", -"wiz", -"wizard", -"wizen", -"wizened", -"wizier", -"wizzen", -"wloka", -"wo", -"woad", -"woader", -"woadman", -"woady", -"woak", -"woald", -"woan", -"wob", -"wobble", -"wobbler", -"wobbly", -"wobster", -"wod", -"woddie", -"wode", -"wodge", -"wodgy", -"woe", -"woeful", -"woesome", -"woevine", -"woeworn", -"woffler", -"woft", -"wog", -"wogiet", -"woibe", -"wokas", -"woke", -"wokowi", -"wold", -"woldy", -"wolf", -"wolfdom", -"wolfen", -"wolfer", -"wolfish", -"wolfkin", -"wolfram", -"wollop", -"wolter", -"wolve", -"wolver", -"woman", -"womanly", -"womb", -"wombat", -"wombed", -"womble", -"womby", -"womera", -"won", -"wonder", -"wone", -"wonegan", -"wong", -"wonga", -"wongen", -"wongshy", -"wongsky", -"woning", -"wonky", -"wonna", -"wonned", -"wonner", -"wonning", -"wonnot", -"wont", -"wonted", -"wonting", -"woo", -"wooable", -"wood", -"woodbin", -"woodcut", -"wooded", -"wooden", -"woodeny", -"woodine", -"wooding", -"woodish", -"woodlet", -"woodly", -"woodman", -"woodrow", -"woodsy", -"woodwax", -"woody", -"wooer", -"woof", -"woofed", -"woofell", -"woofer", -"woofy", -"woohoo", -"wooing", -"wool", -"woold", -"woolder", -"wooled", -"woolen", -"wooler", -"woolert", -"woolly", -"woolman", -"woolsey", -"woom", -"woomer", -"woon", -"woons", -"woorali", -"woorari", -"woosh", -"wootz", -"woozle", -"woozy", -"wop", -"woppish", -"wops", -"worble", -"word", -"wordage", -"worded", -"worder", -"wordily", -"wording", -"wordish", -"wordle", -"wordman", -"wordy", -"wore", -"work", -"workbag", -"workbox", -"workday", -"worked", -"worker", -"working", -"workman", -"workout", -"workpan", -"works", -"worky", -"world", -"worlded", -"worldly", -"worldy", -"worm", -"wormed", -"wormer", -"wormil", -"worming", -"wormy", -"worn", -"wornil", -"worral", -"worried", -"worrier", -"worrit", -"worry", -"worse", -"worsen", -"worser", -"worset", -"worship", -"worst", -"worsted", -"wort", -"worth", -"worthy", -"wosbird", -"wot", -"wote", -"wots", -"wottest", -"wotteth", -"woubit", -"wouch", -"wouf", -"wough", -"would", -"wouldnt", -"wouldst", -"wound", -"wounded", -"wounder", -"wounds", -"woundy", -"wourali", -"wourari", -"wournil", -"wove", -"woven", -"wow", -"wowser", -"wowsery", -"wowt", -"woy", -"wrack", -"wracker", -"wraggle", -"wraith", -"wraithe", -"wraithy", -"wraitly", -"wramp", -"wran", -"wrang", -"wrangle", -"wranny", -"wrap", -"wrapped", -"wrapper", -"wrasse", -"wrastle", -"wrath", -"wrathy", -"wraw", -"wrawl", -"wrawler", -"wraxle", -"wreak", -"wreat", -"wreath", -"wreathe", -"wreathy", -"wreck", -"wrecker", -"wrecky", -"wren", -"wrench", -"wrenlet", -"wrest", -"wrester", -"wrestle", -"wretch", -"wricht", -"wrick", -"wride", -"wried", -"wrier", -"wriest", -"wrig", -"wriggle", -"wriggly", -"wright", -"wring", -"wringer", -"wrinkle", -"wrinkly", -"wrist", -"wristed", -"wrister", -"writ", -"write", -"writee", -"writer", -"writh", -"writhe", -"writhed", -"writhen", -"writher", -"writhy", -"writing", -"written", -"writter", -"wrive", -"wro", -"wrocht", -"wroke", -"wroken", -"wrong", -"wronged", -"wronger", -"wrongly", -"wrossle", -"wrote", -"wroth", -"wrothly", -"wrothy", -"wrought", -"wrox", -"wrung", -"wry", -"wrybill", -"wryly", -"wryneck", -"wryness", -"wrytail", -"wud", -"wuddie", -"wudge", -"wudu", -"wugg", -"wulk", -"wull", -"wullcat", -"wulliwa", -"wumble", -"wumman", -"wummel", -"wun", -"wungee", -"wunna", -"wunner", -"wunsome", -"wup", -"wur", -"wurley", -"wurmal", -"wurrus", -"wurset", -"wurzel", -"wush", -"wusp", -"wuss", -"wusser", -"wust", -"wut", -"wuther", -"wuzu", -"wuzzer", -"wuzzle", -"wuzzy", -"wy", -"wyde", -"wye", -"wyke", -"wyle", -"wymote", -"wyn", -"wynd", -"wyne", -"wynn", -"wype", -"wyson", -"wyss", -"wyve", -"wyver", -"x", -"xanthic", -"xanthin", -"xanthyl", -"xarque", -"xebec", -"xenia", -"xenial", -"xenian", -"xenium", -"xenon", -"xenyl", -"xerafin", -"xerarch", -"xerasia", -"xeric", -"xeriff", -"xerogel", -"xeroma", -"xeronic", -"xerosis", -"xerotes", -"xerotic", -"xi", -"xiphias", -"xiphiid", -"xiphoid", -"xoana", -"xoanon", -"xurel", -"xyla", -"xylan", -"xylate", -"xylem", -"xylene", -"xylenol", -"xylenyl", -"xyletic", -"xylic", -"xylidic", -"xylinid", -"xylite", -"xylitol", -"xylogen", -"xyloid", -"xylol", -"xyloma", -"xylon", -"xylonic", -"xylose", -"xyloyl", -"xylyl", -"xylylic", -"xyphoid", -"xyrid", -"xyst", -"xyster", -"xysti", -"xystos", -"xystum", -"xystus", -"y", -"ya", -"yaba", -"yabber", -"yabbi", -"yabble", -"yabby", -"yabu", -"yacal", -"yacca", -"yachan", -"yacht", -"yachter", -"yachty", -"yad", -"yade", -"yaff", -"yaffle", -"yagger", -"yagi", -"yagua", -"yaguaza", -"yah", -"yahan", -"yahoo", -"yair", -"yaird", -"yaje", -"yajeine", -"yak", -"yakalo", -"yakamik", -"yakin", -"yakka", -"yakman", -"yalb", -"yale", -"yali", -"yalla", -"yallaer", -"yallow", -"yam", -"yamamai", -"yamanai", -"yamen", -"yamilke", -"yammer", -"yamp", -"yampa", -"yamph", -"yamshik", -"yan", -"yander", -"yang", -"yangtao", -"yank", -"yanking", -"yanky", -"yaoort", -"yaourti", -"yap", -"yapa", -"yaply", -"yapness", -"yapok", -"yapp", -"yapped", -"yapper", -"yapping", -"yappish", -"yappy", -"yapster", -"yar", -"yarak", -"yaray", -"yarb", -"yard", -"yardage", -"yardang", -"yardarm", -"yarder", -"yardful", -"yarding", -"yardman", -"yare", -"yareta", -"yark", -"yarke", -"yarl", -"yarly", -"yarm", -"yarn", -"yarnen", -"yarner", -"yarpha", -"yarr", -"yarran", -"yarrow", -"yarth", -"yarthen", -"yarwhip", -"yas", -"yashiro", -"yashmak", -"yat", -"yate", -"yati", -"yatter", -"yaud", -"yauld", -"yaupon", -"yautia", -"yava", -"yaw", -"yawl", -"yawler", -"yawn", -"yawner", -"yawney", -"yawnful", -"yawnily", -"yawning", -"yawnups", -"yawny", -"yawp", -"yawper", -"yawroot", -"yaws", -"yawweed", -"yawy", -"yaxche", -"yaya", -"ycie", -"yday", -"ye", -"yea", -"yeah", -"yealing", -"yean", -"year", -"yeara", -"yeard", -"yearday", -"yearful", -"yearly", -"yearn", -"yearock", -"yearth", -"yeast", -"yeasty", -"yeat", -"yeather", -"yed", -"yede", -"yee", -"yeel", -"yees", -"yegg", -"yeggman", -"yeguita", -"yeld", -"yeldrin", -"yelk", -"yell", -"yeller", -"yelling", -"yelloch", -"yellow", -"yellows", -"yellowy", -"yelm", -"yelmer", -"yelp", -"yelper", -"yelt", -"yen", -"yender", -"yeni", -"yenite", -"yeo", -"yeoman", -"yep", -"yer", -"yerb", -"yerba", -"yercum", -"yerd", -"yere", -"yerga", -"yerk", -"yern", -"yerth", -"yes", -"yese", -"yeso", -"yesso", -"yest", -"yester", -"yestern", -"yesty", -"yet", -"yeta", -"yetapa", -"yeth", -"yether", -"yetlin", -"yeuk", -"yeuky", -"yeven", -"yew", -"yex", -"yez", -"yezzy", -"ygapo", -"yield", -"yielden", -"yielder", -"yieldy", -"yigh", -"yill", -"yilt", -"yin", -"yince", -"yinst", -"yip", -"yird", -"yirk", -"yirm", -"yirn", -"yirr", -"yirth", -"yis", -"yite", -"ym", -"yn", -"ynambu", -"yo", -"yobi", -"yocco", -"yochel", -"yock", -"yockel", -"yodel", -"yodeler", -"yodh", -"yoe", -"yoga", -"yogh", -"yoghurt", -"yogi", -"yogin", -"yogism", -"yogist", -"yogoite", -"yohimbe", -"yohimbi", -"yoi", -"yoick", -"yoicks", -"yojan", -"yojana", -"yok", -"yoke", -"yokeage", -"yokel", -"yokelry", -"yoker", -"yoking", -"yoky", -"yolden", -"yolk", -"yolked", -"yolky", -"yom", -"yomer", -"yon", -"yond", -"yonder", -"yonner", -"yonside", -"yont", -"yook", -"yoop", -"yor", -"yore", -"york", -"yorker", -"yot", -"yote", -"you", -"youd", -"youden", -"youdith", -"youff", -"youl", -"young", -"younger", -"youngly", -"youngun", -"younker", -"youp", -"your", -"yourn", -"yours", -"yoursel", -"youse", -"youth", -"youthen", -"youthy", -"youve", -"youward", -"youze", -"yoven", -"yow", -"yowie", -"yowl", -"yowler", -"yowley", -"yowt", -"yox", -"yoy", -"yperite", -"yr", -"yttria", -"yttric", -"yttrium", -"yuan", -"yuca", -"yucca", -"yuck", -"yuckel", -"yucker", -"yuckle", -"yucky", -"yuft", -"yugada", -"yuh", -"yukkel", -"yulan", -"yule", -"yummy", -"yungan", -"yurt", -"yurta", -"yus", -"yusdrum", -"yutu", -"yuzlik", -"yuzluk", -"z", -"za", -"zabeta", -"zabra", -"zabti", -"zabtie", -"zac", -"zacate", -"zacaton", -"zachun", -"zad", -"zadruga", -"zaffar", -"zaffer", -"zafree", -"zag", -"zagged", -"zain", -"zak", -"zakkeu", -"zaman", -"zamang", -"zamarra", -"zamarro", -"zambo", -"zamorin", -"zamouse", -"zander", -"zanella", -"zant", -"zante", -"zany", -"zanyish", -"zanyism", -"zanze", -"zapas", -"zaphara", -"zapota", -"zaptiah", -"zaptieh", -"zapupe", -"zaqqum", -"zar", -"zareba", -"zarf", -"zarnich", -"zarp", -"zat", -"zati", -"zattare", -"zax", -"zayat", -"zayin", -"zeal", -"zealful", -"zealot", -"zealous", -"zebra", -"zebraic", -"zebrass", -"zebrine", -"zebroid", -"zebrula", -"zebrule", -"zebu", -"zebub", -"zeburro", -"zechin", -"zed", -"zedoary", -"zee", -"zeed", -"zehner", -"zein", -"zeism", -"zeist", -"zel", -"zelator", -"zemeism", -"zemi", -"zemmi", -"zemni", -"zemstvo", -"zenana", -"zendik", -"zenick", -"zenith", -"zenu", -"zeolite", -"zephyr", -"zephyry", -"zequin", -"zer", -"zerda", -"zero", -"zeroize", -"zest", -"zestful", -"zesty", -"zeta", -"zetetic", -"zeugma", -"ziamet", -"ziara", -"ziarat", -"zibet", -"zibetum", -"ziega", -"zieger", -"ziffs", -"zig", -"ziganka", -"zigzag", -"zihar", -"zikurat", -"zillah", -"zimarra", -"zimb", -"zimbi", -"zimme", -"zimmi", -"zimmis", -"zimocca", -"zinc", -"zincate", -"zincic", -"zincide", -"zincify", -"zincing", -"zincite", -"zincize", -"zincke", -"zincky", -"zinco", -"zincous", -"zincum", -"zing", -"zingel", -"zink", -"zinsang", -"zip", -"ziphian", -"zipper", -"zipping", -"zippy", -"zira", -"zirai", -"zircite", -"zircon", -"zither", -"zizz", -"zloty", -"zo", -"zoa", -"zoacum", -"zoaria", -"zoarial", -"zoarium", -"zobo", -"zocco", -"zoccolo", -"zodiac", -"zoea", -"zoeal", -"zoeform", -"zoetic", -"zogan", -"zogo", -"zoic", -"zoid", -"zoisite", -"zoism", -"zoist", -"zoistic", -"zokor", -"zoll", -"zolle", -"zombi", -"zombie", -"zonal", -"zonally", -"zonar", -"zonary", -"zonate", -"zonated", -"zone", -"zoned", -"zonelet", -"zonic", -"zoning", -"zonite", -"zonitid", -"zonoid", -"zonular", -"zonule", -"zonulet", -"zonure", -"zonurid", -"zoo", -"zoocarp", -"zoocyst", -"zooecia", -"zoogamy", -"zoogene", -"zoogeny", -"zoogony", -"zooid", -"zooidal", -"zooks", -"zoolite", -"zoolith", -"zoology", -"zoom", -"zoon", -"zoonal", -"zoonic", -"zoonist", -"zoonite", -"zoonomy", -"zoons", -"zoonule", -"zoopery", -"zoopsia", -"zoosis", -"zootaxy", -"zooter", -"zootic", -"zootomy", -"zootype", -"zoozoo", -"zorgite", -"zoril", -"zorilla", -"zorillo", -"zorro", -"zoster", -"zounds", -"zowie", -"zudda", -"zuisin", -"zumatic", -"zunyite", -"zuza", -"zwitter", -"zyga", -"zygal", -"zygion", -"zygite", -"zygoma", -"zygon", -"zygose", -"zygosis", -"zygote", -"zygotic", -"zygous", -"zymase", -"zyme", -"zymic", -"zymin", -"zymite", -"zymogen", -"zymoid", -"zymome", -"zymomin", -"zymosis", -"zymotic", -"zymurgy", -"zythem", -"zythum" }; - - -const uint32_t word_list_size = sizeof(word_list)/sizeof(word_list[0]); - -void hide_unused_warning() { - (void)word_list_size; - (void)word_list; -} - -} } // eosio::words diff --git a/libraries/wabt b/libraries/wabt index 2f5382661f7bf77cf7a70dcf0543a44fd5025910..bf353aa719c88b7152ee09e7f877a507cb7df27b 160000 --- a/libraries/wabt +++ b/libraries/wabt @@ -1 +1 @@ -Subproject commit 2f5382661f7bf77cf7a70dcf0543a44fd5025910 +Subproject commit bf353aa719c88b7152ee09e7f877a507cb7df27b diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 9b0b17b9d0ac53e605d12bbc9bd3da1f488c145c..8c93df9c48e43c0e47264d2281d32de91a2d6299 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -9,6 +9,7 @@ add_subdirectory(producer_plugin) add_subdirectory(producer_api_plugin) add_subdirectory(history_plugin) add_subdirectory(history_api_plugin) +add_subdirectory(state_history_plugin) add_subdirectory(wallet_plugin) add_subdirectory(wallet_api_plugin) diff --git a/plugins/bnet_plugin/bnet_plugin.cpp b/plugins/bnet_plugin/bnet_plugin.cpp index 4052fce2b30be6dbaf0ace245f0b581ade283c5b..392df4b31ebf3ec36934b9e3dbca39cc8ef08e1f 100644 --- a/plugins/bnet_plugin/bnet_plugin.cpp +++ b/plugins/bnet_plugin/bnet_plugin.cpp @@ -306,7 +306,7 @@ namespace eosio { int next_session_id()const { - static int session_count = 0; + static std::atomic session_count(0); return ++session_count; } @@ -788,7 +788,7 @@ namespace eosio { /// if something changed, the next block doesn't link to the last /// block we sent, local chain must have switched forks - if( nextblock->previous != _last_sent_block_id ) { + if( nextblock->previous != _last_sent_block_id && _last_sent_block_id != block_id_type() ) { if( !is_known_by_peer( nextblock->previous ) ) { _last_sent_block_id = _local_lib_id; _last_sent_block_num = _local_lib; @@ -1041,26 +1041,7 @@ namespace eosio { return false; } - void on( const packed_transaction_ptr& p ) { - peer_ilog(this, "received packed_transaction_ptr"); - if (!p) { - peer_elog(this, "bad packed_transaction_ptr : null pointer"); - EOS_THROW(transaction_exception, "bad transaction"); - } - if( app().get_plugin().chain().get_read_mode() == chain::db_read_mode::READ_ONLY ) - return; - - // ilog( "recv trx ${n}", ("n", id) ); - if( p->expiration() < fc::time_point::now() ) return; - - // get id via get_uncached_id() as packed_transaction.id() mutates internal transaction state - const auto& id = p->get_uncached_id(); - - if( mark_transaction_known_by_peer( id ) ) - return; - - app().get_channel().publish(p); - } + void on( const packed_transaction_ptr& p ); void on_write( boost::system::error_code ec, std::size_t bytes_transferred ) { boost::ignore_unused(bytes_transferred); @@ -1402,8 +1383,10 @@ namespace eosio { if( app().get_plugin().chain().get_read_mode() == chain::db_read_mode::READ_ONLY ) { - my->_request_trx = false; - ilog( "setting bnet-no-trx to true since in read-only mode" ); + if (my->_request_trx) { + my->_request_trx = false; + ilog( "forced bnet-no-trx to true since in read-only mode" ); + } } const auto address = boost::asio::ip::make_address( my->_bnet_endpoint_address ); @@ -1557,4 +1540,24 @@ namespace eosio { } + void session::on( const packed_transaction_ptr& p ) { + peer_ilog(this, "received packed_transaction_ptr"); + if (!p) { + peer_elog(this, "bad packed_transaction_ptr : null pointer"); + EOS_THROW(transaction_exception, "bad transaction"); + } + if( !_net_plugin->_request_trx ) + return; + + // ilog( "recv trx ${n}", ("n", id) ); + if( p->expiration() < fc::time_point::now() ) return; + + // get id via get_uncached_id() as packed_transaction.id() mutates internal transaction state + const auto& id = p->get_uncached_id(); + + if( mark_transaction_known_by_peer( id ) ) + return; + + app().get_channel().publish(p); + } } /// namespace eosio diff --git a/plugins/chain_plugin/chain_plugin.cpp b/plugins/chain_plugin/chain_plugin.cpp index 2603a87178b87b475aa71081c1f49b2d7eea7023..ad67318528b1fe78a42dad19d3797d839acdf1df 100644 --- a/plugins/chain_plugin/chain_plugin.cpp +++ b/plugins/chain_plugin/chain_plugin.cpp @@ -18,10 +18,6 @@ #include -#include -#include -#include - #include #include #include @@ -222,6 +218,8 @@ void chain_plugin::set_program_options(options_description& cli, options_descrip ("chain-state-db-guard-size-mb", bpo::value()->default_value(config::default_state_guard_size / (1024 * 1024)), "Safely shut down node when free space remaining in the chain state database drops below this size (in MiB).") ("reversible-blocks-db-size-mb", bpo::value()->default_value(config::default_reversible_cache_size / (1024 * 1024)), "Maximum size (in MiB) of the reversible blocks database") ("reversible-blocks-db-guard-size-mb", bpo::value()->default_value(config::default_reversible_guard_size / (1024 * 1024)), "Safely shut down node when free space remaining in the reverseible blocks database drops below this size (in MiB).") + ("chain-threads", bpo::value()->default_value(config::default_controller_thread_pool_size), + "Number of worker threads in controller thread pool") ("contracts-console", bpo::bool_switch()->default_value(false), "print contract's output to console") ("actor-whitelist", boost::program_options::value>()->composing()->multitoken(), @@ -236,6 +234,8 @@ void chain_plugin::set_program_options(options_description& cli, options_descrip "Action (in the form code::action) added to action blacklist (may specify multiple times)") ("key-blacklist", boost::program_options::value>()->composing()->multitoken(), "Public key added to blacklist of keys that should not be included in authorities (may specify multiple times)") + ("sender-bypass-whiteblacklist", boost::program_options::value>()->composing()->multitoken(), + "Deferred transactions sent by accounts in this list do not have any of the subjective whitelist/blacklist checks applied to them (may specify multiple times)") ("read-mode", boost::program_options::value()->default_value(eosio::chain::db_read_mode::SPECULATIVE), "Database read mode (\"speculative\", \"head\", or \"read-only\").\n"// or \"irreversible\").\n" "In \"speculative\" mode database contains changes done up to the head block plus changes made by transactions not yet included to the blockchain.\n" @@ -343,6 +343,7 @@ void chain_plugin::plugin_initialize(const variables_map& options) { my->chain_config = controller::config(); + LOAD_VALUE_SET( options, "sender-bypass-whiteblacklist", my->chain_config->sender_bypass_whiteblacklist ); LOAD_VALUE_SET( options, "actor-whitelist", my->chain_config->actor_whitelist ); LOAD_VALUE_SET( options, "actor-blacklist", my->chain_config->actor_blacklist ); LOAD_VALUE_SET( options, "contract-whitelist", my->chain_config->contract_whitelist ); @@ -419,6 +420,12 @@ void chain_plugin::plugin_initialize(const variables_map& options) { if( options.count( "reversible-blocks-db-guard-size-mb" )) my->chain_config->reversible_guard_size = options.at( "reversible-blocks-db-guard-size-mb" ).as() * 1024 * 1024; + if( options.count( "chain-threads" )) { + my->chain_config->thread_pool_size = options.at( "chain-threads" ).as(); + EOS_ASSERT( my->chain_config->thread_pool_size > 0, plugin_config_exception, + "chain-threads ${num} must be greater than 0", ("num", my->chain_config->thread_pool_size) ); + } + if( my->wasm_runtime ) my->chain_config->wasm_runtime = *my->wasm_runtime; @@ -565,12 +572,17 @@ void chain_plugin::plugin_initialize(const variables_map& options) { } } else { - if( options.count( "genesis-json" )) { - EOS_ASSERT( !fc::exists( my->blocks_dir / "blocks.log" ), - plugin_config_exception, - "Genesis state can only be set on a fresh blockchain." ); + bfs::path genesis_file; + bool genesis_timestamp_specified = false; + fc::optional existing_genesis; - auto genesis_file = options.at( "genesis-json" ).as(); + if( fc::exists( my->blocks_dir / "blocks.log" ) ) { + my->chain_config->genesis = block_log::extract_genesis_state( my->blocks_dir ); + existing_genesis = my->chain_config->genesis; + } + + if( options.count( "genesis-json" )) { + genesis_file = options.at( "genesis-json" ).as(); if( genesis_file.is_relative()) { genesis_file = bfs::current_path() / genesis_file; } @@ -581,28 +593,32 @@ void chain_plugin::plugin_initialize(const variables_map& options) { ("genesis", genesis_file.generic_string())); my->chain_config->genesis = fc::json::from_file( genesis_file ).as(); + } - ilog( "Using genesis state provided in '${genesis}'", ("genesis", genesis_file.generic_string())); + if( options.count( "genesis-timestamp" ) ) { + my->chain_config->genesis.initial_timestamp = calculate_genesis_timestamp( options.at( "genesis-timestamp" ).as() ); + genesis_timestamp_specified = true; + } - if( options.count( "genesis-timestamp" )) { - my->chain_config->genesis.initial_timestamp = calculate_genesis_timestamp( - options.at( "genesis-timestamp" ).as()); + if( !existing_genesis ) { + if( !genesis_file.empty() ) { + if( genesis_timestamp_specified ) { + ilog( "Using genesis state provided in '${genesis}' but with adjusted genesis timestamp", + ("genesis", genesis_file.generic_string()) ); + } else { + ilog( "Using genesis state provided in '${genesis}'", ("genesis", genesis_file.generic_string())); + } + wlog( "Starting up fresh blockchain with provided genesis state." ); + } else if( genesis_timestamp_specified ) { + wlog( "Starting up fresh blockchain with default genesis state but with adjusted genesis timestamp." ); + } else { + wlog( "Starting up fresh blockchain with default genesis state." ); } - - wlog( "Starting up fresh blockchain with provided genesis state." ); - } else if( options.count( "genesis-timestamp" )) { - EOS_ASSERT( !fc::exists( my->blocks_dir / "blocks.log" ), - plugin_config_exception, - "Genesis state can only be set on a fresh blockchain." ); - - my->chain_config->genesis.initial_timestamp = calculate_genesis_timestamp( - options.at( "genesis-timestamp" ).as()); - - wlog( "Starting up fresh blockchain with default genesis state but with adjusted genesis timestamp." ); - } else if( fc::is_regular_file( my->blocks_dir / "blocks.log" )) { - my->chain_config->genesis = block_log::extract_genesis_state( my->blocks_dir ); } else { - wlog( "Starting up fresh blockchain with default genesis state." ); + EOS_ASSERT( my->chain_config->genesis == *existing_genesis, plugin_config_exception, + "Genesis state provided via command line arguments does not match the existing genesis state in blocks.log. " + "It is not necessary to provide genesis state arguments when a blocks.log file already exists." + ); } } @@ -688,13 +704,14 @@ void chain_plugin::plugin_initialize(const variables_map& options) { void chain_plugin::plugin_startup() { try { try { + auto shutdown = [](){ return app().is_quiting(); }; if (my->snapshot_path) { auto infile = std::ifstream(my->snapshot_path->generic_string(), (std::ios::in | std::ios::binary)); auto reader = std::make_shared(infile); - my->chain->startup(reader); + my->chain->startup(shutdown, reader); infile.close(); } else { - my->chain->startup(); + my->chain->startup(shutdown); } } catch (const database_guard_exception& e) { log_guard_exception(e); @@ -734,10 +751,6 @@ void chain_apis::read_write::validate() const { EOS_ASSERT( db.get_read_mode() != chain::db_read_mode::READ_ONLY, missing_chain_api_plugin_exception, "Not allowed, node in read-only mode" ); } -chain_apis::read_write chain_plugin::get_read_write_api() { - return chain_apis::read_write(chain(), get_abi_serializer_max_time()); -} - void chain_plugin::accept_block(const signed_block_ptr& block ) { my->incoming_block_sync_method(block); } @@ -992,10 +1005,19 @@ namespace chain_apis { const string read_only::KEYi64 = "i64"; +template +std::string itoh(I n, size_t hlen = sizeof(I)<<1) { + static const char* digits = "0123456789abcdef"; + std::string r(hlen, '0'); + for(size_t i = 0, j = (hlen - 1) * 4 ; i < hlen; ++i, j -= 4) + r[i] = digits[(n>>j) & 0x0f]; + return r; +} + read_only::get_info_results read_only::get_info(const read_only::get_info_params&) const { const auto& rm = db.get_resource_limits_manager(); return { - eosio::utilities::common::itoh(static_cast(app().version())), + itoh(static_cast(app().version())), db.get_chain_id(), db.fork_db_head_block_num(), db.last_irreversible_block_num(), @@ -1088,6 +1110,19 @@ uint64_t convert_to_type(const string& str, const string& desc) { } } +template<> +double convert_to_type(const string& str, const string& desc) { + double val{}; + try { + val = fc::variant(str).as(); + } FC_RETHROW_EXCEPTIONS(warn, "Could not convert ${desc} string '${str}' to key type.", ("desc", desc)("str",str) ) + + EOS_ASSERT( !std::isnan(val), chain::contract_table_query_exception, + "Converted ${desc} string '${str}' to NaN which is not a permitted value for the key type", ("desc", desc)("str",str) ); + + return val; +} + abi_def get_abi( const controller& db, const name& account ) { const auto &d = db.db(); const account_object *code_accnt = d.find(account); @@ -1166,51 +1201,57 @@ read_only::get_table_rows_result read_only::get_table_rows( const read_only::get } read_only::get_table_by_scope_result read_only::get_table_by_scope( const read_only::get_table_by_scope_params& p )const { + read_only::get_table_by_scope_result result; const auto& d = db.db(); + const auto& idx = d.get_index(); - decltype(idx.lower_bound(boost::make_tuple(0, 0, 0))) lower; - decltype(idx.upper_bound(boost::make_tuple(0, 0, 0))) upper; + auto lower_bound_lookup_tuple = std::make_tuple( p.code.value, std::numeric_limits::lowest(), p.table.value ); + auto upper_bound_lookup_tuple = std::make_tuple( p.code.value, std::numeric_limits::max(), + (p.table.empty() ? std::numeric_limits::max() : p.table.value) ); - if (p.lower_bound.size()) { + if( p.lower_bound.size() ) { uint64_t scope = convert_to_type(p.lower_bound, "lower_bound scope"); - lower = idx.lower_bound( boost::make_tuple(p.code, scope, p.table)); - } else { - lower = idx.lower_bound(boost::make_tuple(p.code, 0, p.table)); + std::get<1>(lower_bound_lookup_tuple) = scope; } - if (p.upper_bound.size()) { + + if( p.upper_bound.size() ) { uint64_t scope = convert_to_type(p.upper_bound, "upper_bound scope"); - upper = idx.lower_bound( boost::make_tuple(p.code, scope, 0)); - } else { - upper = idx.lower_bound(boost::make_tuple((uint64_t)p.code + 1, 0, 0)); + std::get<1>(upper_bound_lookup_tuple) = scope; } - auto end = fc::time_point::now() + fc::microseconds(1000 * 10); /// 10ms max time - unsigned int count = 0; - auto itr = lower; - read_only::get_table_by_scope_result result; - for (; itr != upper; ++itr) { - if (p.table && itr->table != p.table) { - if (fc::time_point::now() > end) { - break; - } - continue; + if( upper_bound_lookup_tuple < lower_bound_lookup_tuple ) + return result; + + auto walk_table_range = [&]( auto itr, auto end_itr ) { + auto cur_time = fc::time_point::now(); + auto end_time = cur_time + fc::microseconds(1000 * 10); /// 10ms max time + for( unsigned int count = 0; cur_time <= end_time && count < p.limit && itr != end_itr; ++itr, cur_time = fc::time_point::now() ) { + if( p.table && itr->table != p.table ) continue; + + result.rows.push_back( {itr->code, itr->scope, itr->table, itr->payer, itr->count} ); + + ++count; } - result.rows.push_back({itr->code, itr->scope, itr->table, itr->payer, itr->count}); - if (++count == p.limit || fc::time_point::now() > end) { - ++itr; - break; + if( itr != end_itr ) { + result.more = string(itr->scope); } + }; + + auto lower = idx.lower_bound( lower_bound_lookup_tuple ); + auto upper = idx.upper_bound( upper_bound_lookup_tuple ); + if( p.reverse && *p.reverse ) { + walk_table_range( boost::make_reverse_iterator(upper), boost::make_reverse_iterator(lower) ); + } else { + walk_table_range( lower, upper ); } - if (itr != upper) { - result.more = (string)itr->scope; - } + return result; } vector read_only::get_currency_balance( const read_only::get_currency_balance_params& p )const { const abi_def abi = eosio::chain_apis::get_abi( db, p.code ); - auto table_type = get_table_type( abi, "accounts" ); + (void)get_table_type( abi, "accounts" ); vector results; walk_key_value_table(p.code, p.account, N(accounts), [&](const key_value_object& obj){ @@ -1237,7 +1278,7 @@ fc::variant read_only::get_currency_stats( const read_only::get_currency_stats_p fc::mutable_variant_object results; const abi_def abi = eosio::chain_apis::get_abi( db, p.code ); - auto table_type = get_table_type( abi, "stat" ); + (void)get_table_type( abi, "stat" ); uint64_t scope = ( eosio::chain::string_to_symbol( 0, boost::algorithm::to_upper_copy(p.symbol).c_str() ) >> 8 ); @@ -1585,17 +1626,12 @@ read_only::get_code_results read_only::get_code( const get_code_params& params ) EOS_ASSERT( params.code_as_wasm, unsupported_feature, "Returning WAST from get_code is no longer supported" ); if( accnt.code.size() ) { - if (params.code_as_wasm) { - result.wasm = string(accnt.code.begin(), accnt.code.end()); - } else { - result.wast = wasm_to_wast( (const uint8_t*)accnt.code.data(), accnt.code.size(), true ); - } + result.wasm = string(accnt.code.begin(), accnt.code.end()); result.code_hash = fc::sha256::hash( accnt.code.data(), accnt.code.size() ); } abi_def abi; if( abi_serializer::to_abi(accnt.abi, abi) ) { - result.abi = std::move(abi); } @@ -1693,7 +1729,7 @@ read_only::get_account_results read_only::get_account( const get_account_params& auto core_symbol = extract_core_symbol(); - if (params.expected_core_symbol.valid()) + if (params.expected_core_symbol.valid()) core_symbol = *(params.expected_core_symbol); const auto* t_id = d.find(boost::make_tuple( token_code, params.account_name, N(accounts) )); diff --git a/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp b/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp index 0b69a6af89a0edd50cbe4388ecc6df6824738459..832f0b2448570c7f7cffa9792fab12099f90c0b8 100644 --- a/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp +++ b/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp @@ -55,7 +55,7 @@ struct permission { template struct resolver_factory; -// see specialization for uint64_t in source file +// see specializations for uint64_t and double in source file template Type convert_to_type(const string& str, const string& desc) { try { @@ -66,6 +66,9 @@ Type convert_to_type(const string& str, const string& desc) { template<> uint64_t convert_to_type(const string& str, const string& desc); +template<> +double convert_to_type(const string& str, const string& desc); + class read_only { const controller& db; const fc::microseconds abi_serializer_max_time; @@ -269,6 +272,8 @@ public: string key_type; // type of key specified by index_position string index_position; // 1 - primary (first), 2 - secondary index (in order defined by multi_index), 3 - third index, etc string encode_type{"dec"}; //dec, hex , default=dec + optional reverse; + optional show_payer; // show RAM pyer }; struct get_table_rows_result { @@ -284,6 +289,7 @@ public: string lower_bound; // lower bound of scope, optional string upper_bound; // upper bound of scope, optional uint32_t limit = 10; + optional reverse; }; struct get_table_by_scope_result_row { name code; @@ -398,58 +404,78 @@ public: const uint64_t table_with_index = get_table_index_name(p, primary); const auto* t_id = d.find(boost::make_tuple(p.code, scope, p.table)); const auto* index_t_id = d.find(boost::make_tuple(p.code, scope, table_with_index)); - if (t_id != nullptr && index_t_id != nullptr) { - const auto& secidx = d.get_index(); - decltype(index_t_id->id) low_tid(index_t_id->id._id); - decltype(index_t_id->id) next_tid(index_t_id->id._id + 1); - auto lower = secidx.lower_bound(boost::make_tuple(low_tid)); - auto upper = secidx.lower_bound(boost::make_tuple(next_tid)); + if( t_id != nullptr && index_t_id != nullptr ) { + using secondary_key_type = std::result_of_t; + static_assert( std::is_same::value, "Return type of conv does not match type of secondary key for IndexType" ); - if (p.lower_bound.size()) { - if (p.key_type == "name") { + const auto& secidx = d.get_index(); + auto lower_bound_lookup_tuple = std::make_tuple( index_t_id->id._id, + eosio::chain::secondary_key_traits::true_lowest(), + std::numeric_limits::lowest() ); + auto upper_bound_lookup_tuple = std::make_tuple( index_t_id->id._id, + eosio::chain::secondary_key_traits::true_highest(), + std::numeric_limits::max() ); + + if( p.lower_bound.size() ) { + if( p.key_type == "name" ) { name s(p.lower_bound); SecKeyType lv = convert_to_type( s.to_string(), "lower_bound name" ); // avoids compiler error - lower = secidx.lower_bound( boost::make_tuple( low_tid, conv( lv ))); + std::get<1>(lower_bound_lookup_tuple) = conv( lv ); } else { SecKeyType lv = convert_to_type( p.lower_bound, "lower_bound" ); - lower = secidx.lower_bound( boost::make_tuple( low_tid, conv( lv ))); + std::get<1>(lower_bound_lookup_tuple) = conv( lv ); } } - if (p.upper_bound.size()) { - if (p.key_type == "name") { + + if( p.upper_bound.size() ) { + if( p.key_type == "name" ) { name s(p.upper_bound); SecKeyType uv = convert_to_type( s.to_string(), "upper_bound name" ); - upper = secidx.lower_bound( boost::make_tuple( low_tid, conv( uv ))); + std::get<1>(upper_bound_lookup_tuple) = conv( uv ); } else { SecKeyType uv = convert_to_type( p.upper_bound, "upper_bound" ); - upper = secidx.lower_bound( boost::make_tuple( low_tid, conv( uv ))); + std::get<1>(upper_bound_lookup_tuple) = conv( uv ); } } - vector data; - - auto end = fc::time_point::now() + fc::microseconds(1000 * 10); /// 10ms max time - - unsigned int count = 0; - auto itr = lower; - for (; itr != upper; ++itr) { - - const auto* itr2 = d.find(boost::make_tuple(t_id->id, itr->primary_key)); - if (itr2 == nullptr) continue; - copy_inline_row(*itr2, data); - - if (p.json) { - result.rows.emplace_back( abis.binary_to_variant( abis.get_table_type(p.table), data, abi_serializer_max_time, shorten_abi_errors ) ); - } else { - result.rows.emplace_back(fc::variant(data)); + if( upper_bound_lookup_tuple < lower_bound_lookup_tuple ) + return result; + + auto walk_table_row_range = [&]( auto itr, auto end_itr ) { + auto cur_time = fc::time_point::now(); + auto end_time = cur_time + fc::microseconds(1000 * 10); /// 10ms max time + vector data; + for( unsigned int count = 0; cur_time <= end_time && count < p.limit && itr != end_itr; ++itr, cur_time = fc::time_point::now() ) { + const auto* itr2 = d.find( boost::make_tuple(t_id->id, itr->primary_key) ); + if( itr2 == nullptr ) continue; + copy_inline_row(*itr2, data); + + fc::variant data_var; + if( p.json ) { + data_var = abis.binary_to_variant( abis.get_table_type(p.table), data, abi_serializer_max_time, shorten_abi_errors ); + } else { + data_var = fc::variant( data ); + } + + if( p.show_payer && *p.show_payer ) { + result.rows.emplace_back( fc::mutable_variant_object("data", std::move(data_var))("payer", itr->payer) ); + } else { + result.rows.emplace_back( std::move(data_var) ); + } + + ++count; } - - if (++count == p.limit || fc::time_point::now() > end) { - break; + if( itr != end_itr ) { + result.more = true; } - } - if (itr != upper) { - result.more = true; + }; + + auto lower = secidx.lower_bound( lower_bound_lookup_tuple ); + auto upper = secidx.upper_bound( upper_bound_lookup_tuple ); + if( p.reverse && *p.reverse ) { + walk_table_row_range( boost::make_reverse_iterator(upper), boost::make_reverse_iterator(lower) ); + } else { + walk_table_row_range( lower, upper ); } } return result; @@ -465,53 +491,65 @@ public: abi_serializer abis; abis.set_abi(abi, abi_serializer_max_time); const auto* t_id = d.find(boost::make_tuple(p.code, scope, p.table)); - if (t_id != nullptr) { + if( t_id != nullptr ) { const auto& idx = d.get_index(); - decltype(t_id->id) next_tid(t_id->id._id + 1); - auto lower = idx.lower_bound(boost::make_tuple(t_id->id)); - auto upper = idx.lower_bound(boost::make_tuple(next_tid)); + auto lower_bound_lookup_tuple = std::make_tuple( t_id->id, std::numeric_limits::lowest() ); + auto upper_bound_lookup_tuple = std::make_tuple( t_id->id, std::numeric_limits::max() ); - if (p.lower_bound.size()) { - if (p.key_type == "name") { + if( p.lower_bound.size() ) { + if( p.key_type == "name" ) { name s(p.lower_bound); - lower = idx.lower_bound( boost::make_tuple( t_id->id, s.value )); + std::get<1>(lower_bound_lookup_tuple) = s.value; } else { auto lv = convert_to_type( p.lower_bound, "lower_bound" ); - lower = idx.lower_bound( boost::make_tuple( t_id->id, lv )); + std::get<1>(lower_bound_lookup_tuple) = lv; } } - if (p.upper_bound.size()) { - if (p.key_type == "name") { + + if( p.upper_bound.size() ) { + if( p.key_type == "name" ) { name s(p.upper_bound); - upper = idx.lower_bound( boost::make_tuple( t_id->id, s.value )); + std::get<1>(upper_bound_lookup_tuple) = s.value; } else { auto uv = convert_to_type( p.upper_bound, "upper_bound" ); - upper = idx.lower_bound( boost::make_tuple( t_id->id, uv )); + std::get<1>(upper_bound_lookup_tuple) = uv; } } - vector data; - - auto end = fc::time_point::now() + fc::microseconds(1000 * 10); /// 10ms max time - - unsigned int count = 0; - auto itr = lower; - for (; itr != upper; ++itr) { - copy_inline_row(*itr, data); - - if (p.json) { - result.rows.emplace_back( abis.binary_to_variant( abis.get_table_type(p.table), data, abi_serializer_max_time, shorten_abi_errors ) ); - } else { - result.rows.emplace_back(fc::variant(data)); + if( upper_bound_lookup_tuple < lower_bound_lookup_tuple ) + return result; + + auto walk_table_row_range = [&]( auto itr, auto end_itr ) { + auto cur_time = fc::time_point::now(); + auto end_time = cur_time + fc::microseconds(1000 * 10); /// 10ms max time + vector data; + for( unsigned int count = 0; cur_time <= end_time && count < p.limit && itr != end_itr; ++count, ++itr, cur_time = fc::time_point::now() ) { + copy_inline_row(*itr, data); + + fc::variant data_var; + if( p.json ) { + data_var = abis.binary_to_variant( abis.get_table_type(p.table), data, abi_serializer_max_time, shorten_abi_errors ); + } else { + data_var = fc::variant( data ); + } + + if( p.show_payer && *p.show_payer ) { + result.rows.emplace_back( fc::mutable_variant_object("data", std::move(data_var))("payer", itr->payer) ); + } else { + result.rows.emplace_back( std::move(data_var) ); + } } - - if (++count == p.limit || fc::time_point::now() > end) { - ++itr; - break; + if( itr != end_itr ) { + result.more = true; } - } - if (itr != upper) { - result.more = true; + }; + + auto lower = idx.lower_bound( lower_bound_lookup_tuple ); + auto upper = idx.upper_bound( upper_bound_lookup_tuple ); + if( p.reverse && *p.reverse ) { + walk_table_row_range( boost::make_reverse_iterator(upper), boost::make_reverse_iterator(lower) ); + } else { + walk_table_row_range( lower, upper ); } } return result; @@ -622,7 +660,7 @@ public: void plugin_shutdown(); chain_apis::read_only get_read_only_api() const { return chain_apis::read_only(chain(), get_abi_serializer_max_time()); } - chain_apis::read_write get_read_write_api(); + chain_apis::read_write get_read_write_api() { return chain_apis::read_write(chain(), get_abi_serializer_max_time()); } void accept_block( const chain::signed_block_ptr& block ); void accept_transaction(const chain::packed_transaction& trx, chain::plugin_interface::next_function next); @@ -672,10 +710,10 @@ FC_REFLECT(eosio::chain_apis::read_only::get_block_header_state_params, (block_n FC_REFLECT( eosio::chain_apis::read_write::push_transaction_results, (transaction_id)(processed) ) -FC_REFLECT( eosio::chain_apis::read_only::get_table_rows_params, (json)(code)(scope)(table)(table_key)(lower_bound)(upper_bound)(limit)(key_type)(index_position)(encode_type) ) +FC_REFLECT( eosio::chain_apis::read_only::get_table_rows_params, (json)(code)(scope)(table)(table_key)(lower_bound)(upper_bound)(limit)(key_type)(index_position)(encode_type)(reverse)(show_payer) ) FC_REFLECT( eosio::chain_apis::read_only::get_table_rows_result, (rows)(more) ); -FC_REFLECT( eosio::chain_apis::read_only::get_table_by_scope_params, (code)(table)(lower_bound)(upper_bound)(limit) ) +FC_REFLECT( eosio::chain_apis::read_only::get_table_by_scope_params, (code)(table)(lower_bound)(upper_bound)(limit)(reverse) ) FC_REFLECT( eosio::chain_apis::read_only::get_table_by_scope_result_row, (code)(scope)(table)(payer)(count)); FC_REFLECT( eosio::chain_apis::read_only::get_table_by_scope_result, (rows)(more) ); diff --git a/plugins/faucet_testnet_plugin/faucet_testnet_plugin.cpp b/plugins/faucet_testnet_plugin/faucet_testnet_plugin.cpp index 55cbf8eb8619eaba12ab2b61646b15d99f70b3b8..39374e692cda844e0b826652b2b2318903b56c99 100644 --- a/plugins/faucet_testnet_plugin/faucet_testnet_plugin.cpp +++ b/plugins/faucet_testnet_plugin/faucet_testnet_plugin.cpp @@ -4,7 +4,6 @@ */ #include #include -#include #include #include diff --git a/plugins/net_plugin/net_plugin.cpp b/plugins/net_plugin/net_plugin.cpp index 9ee380b666fee132fab190546231ce0fb17e8791..8979cd53095d140b5fea4068c6b30e80d896fedf 100644 --- a/plugins/net_plugin/net_plugin.cpp +++ b/plugins/net_plugin/net_plugin.cpp @@ -11,7 +11,6 @@ #include #include #include -#include #include #include @@ -1514,9 +1513,10 @@ namespace eosio { req.req_blocks.mode = catch_up; for (auto cc : my_impl->connections) { if (cc->fork_head == id || - cc->fork_head_num > num) + cc->fork_head_num > num) { req.req_blocks.mode = none; - break; + break; + } } if( req.req_blocks.mode == catch_up ) { c->fork_head = id; @@ -2379,7 +2379,7 @@ namespace eosio { request_message req; bool send_req = false; if (msg.known_trx.mode != none) { - fc_dlog(logger,"this is a ${m} notice with ${n} blocks", ("m",modes_str(msg.known_trx.mode))("n",msg.known_trx.pending)); + fc_dlog(logger,"this is a ${m} notice with ${n} transactions", ("m",modes_str(msg.known_trx.mode))("n",msg.known_trx.pending)); } switch (msg.known_trx.mode) { case none: @@ -2413,9 +2413,6 @@ namespace eosio { } switch (msg.known_blocks.mode) { case none : { - if (msg.known_trx.mode != normal) { - return; - } break; } case last_irr_catch_up: diff --git a/plugins/producer_plugin/CMakeLists.txt b/plugins/producer_plugin/CMakeLists.txt index d7f9188d5bbb14fbfe42ee4a633a23b8c6dc9eb7..fe161f8d91320cd6c2614bd80b347e87e58a5acf 100644 --- a/plugins/producer_plugin/CMakeLists.txt +++ b/plugins/producer_plugin/CMakeLists.txt @@ -5,6 +5,6 @@ add_library( producer_plugin ${HEADERS} ) -target_link_libraries( producer_plugin chain_plugin http_client_plugin appbase eosio_chain eos_utilities ) +target_link_libraries( producer_plugin chain_plugin http_client_plugin appbase eosio_chain ) target_include_directories( producer_plugin PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" "${CMAKE_CURRENT_SOURCE_DIR}/../chain_interface/include" ) diff --git a/plugins/producer_plugin/producer_plugin.cpp b/plugins/producer_plugin/producer_plugin.cpp index c46452b5fb40e08711dae0a66741362c9b6c148a..5d2cd5637c40f87bdcf6796937a1ec6df38c30be 100644 --- a/plugins/producer_plugin/producer_plugin.cpp +++ b/plugins/producer_plugin/producer_plugin.cpp @@ -285,18 +285,22 @@ class producer_plugin_impl : public std::enable_shared_from_thisid())); + auto id = block->id(); - EOS_ASSERT( block->timestamp < (fc::time_point::now() + fc::seconds(7)), block_from_the_future, "received a block from the future, ignoring it" ); + fc_dlog(_log, "received incoming block ${id}", ("id", id)); + EOS_ASSERT( block->timestamp < (fc::time_point::now() + fc::seconds( 7 )), block_from_the_future, + "received a block from the future, ignoring it: ${id}", ("id", id) ); chain::controller& chain = app().get_plugin().chain(); /* de-dupe here... no point in aborting block if we already know the block */ - auto id = block->id(); auto existing = chain.fetch_block_by_id( id ); if( existing ) { return; } + // start processing of block + auto bsf = chain.create_block_state_future( block ); + // abort the pending block chain.abort_block(); @@ -308,7 +312,7 @@ class producer_plugin_impl : public std::enable_shared_from_this().handle_guard_exception(e); return; diff --git a/plugins/state_history_plugin/.clang-format b/plugins/state_history_plugin/.clang-format new file mode 100644 index 0000000000000000000000000000000000000000..42dd5b7832c6f62bdd19484b1d784b6f461d48db --- /dev/null +++ b/plugins/state_history_plugin/.clang-format @@ -0,0 +1,8 @@ +BasedOnStyle: LLVM +IndentWidth: 3 +ColumnLimit: 120 +PointerAlignment: Left +AlwaysBreakTemplateDeclarations: true +AlignConsecutiveAssignments: true +AlignConsecutiveDeclarations: true +BreakConstructorInitializers: BeforeComma diff --git a/plugins/state_history_plugin/CMakeLists.txt b/plugins/state_history_plugin/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..21f0e10a90072afdfc412e7a7320dc574b5ba9a6 --- /dev/null +++ b/plugins/state_history_plugin/CMakeLists.txt @@ -0,0 +1,8 @@ +file(GLOB HEADERS "include/eosio/state_history_plugin/*.hpp") +add_library( state_history_plugin + state_history_plugin.cpp + state_history_plugin_abi.cpp + ${HEADERS} ) + +target_link_libraries( state_history_plugin chain_plugin eosio_chain appbase ) +target_include_directories( state_history_plugin PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" ) diff --git a/plugins/state_history_plugin/include/eosio/state_history_plugin/state_history_log.hpp b/plugins/state_history_plugin/include/eosio/state_history_plugin/state_history_log.hpp new file mode 100644 index 0000000000000000000000000000000000000000..a580529c5d59130e6d2e776486d8d5c27aea6736 --- /dev/null +++ b/plugins/state_history_plugin/include/eosio/state_history_plugin/state_history_log.hpp @@ -0,0 +1,279 @@ +/** + * @file + * @copyright defined in eos/LICENSE.txt + */ +#pragma once + +#include +#include +#include + +#include +#include +#include + +namespace eosio { + +/* + * *.log: + * +---------+----------------+-----------+------------------+-----+---------+----------------+ + * | Entry i | Pos of Entry i | Entry i+1 | Pos of Entry i+1 | ... | Entry z | Pos of Entry z | + * +---------+----------------+-----------+------------------+-----+---------+----------------+ + * + * *.index: + * +-----------+-------------+-----+-----------+ + * | Summary i | Summary i+1 | ... | Summary z | + * +-----------+-------------+-----+-----------+ + * + * each entry: + * uint32_t block_num + * block_id_type block_id + * uint64_t size of payload + * uint8_t version + * payload + * + * each summary: + * uint64_t position of entry in *.log + * + * state payload: + * uint32_t size of deltas + * char[] deltas + */ + +// todo: look into switching this to serialization instead of memcpy +// todo: consider reworking versioning +// todo: consider dropping block_num since it's included in block_id +// todo: currently only checks version on the first record. Need in recover_blocks +struct state_history_log_header { + uint32_t block_num = 0; + chain::block_id_type block_id; + uint64_t payload_size = 0; + uint8_t version = 0; +}; + +struct state_history_summary { + uint64_t pos = 0; +}; + +class state_history_log { + private: + const char* const name = ""; + std::string log_filename; + std::string index_filename; + std::fstream log; + std::fstream index; + uint32_t _begin_block = 0; + uint32_t _end_block = 0; + chain::block_id_type last_block_id; + + public: + state_history_log(const char* const name, std::string log_filename, std::string index_filename) + : name(name) + , log_filename(std::move(log_filename)) + , index_filename(std::move(index_filename)) { + open_log(); + open_index(); + } + + uint32_t begin_block() const { return _begin_block; } + uint32_t end_block() const { return _end_block; } + + template + void write_entry(const state_history_log_header& header, const chain::block_id_type& prev_id, F write_payload) { + EOS_ASSERT(_begin_block == _end_block || header.block_num <= _end_block, chain::plugin_exception, + "missed a block in ${name}.log", ("name", name)); + + if (_begin_block != _end_block && header.block_num > _begin_block) { + if (header.block_num == _end_block) { + EOS_ASSERT(prev_id == last_block_id, chain::plugin_exception, "missed a fork change in ${name}.log", + ("name", name)); + } else { + state_history_log_header prev; + get_entry(header.block_num - 1, prev); + EOS_ASSERT(prev_id == prev.block_id, chain::plugin_exception, "missed a fork change in ${name}.log", + ("name", name)); + } + } + + if (header.block_num < _end_block) + truncate(header.block_num); + log.seekg(0, std::ios_base::end); + uint64_t pos = log.tellg(); + log.write((char*)&header, sizeof(header)); + write_payload(log); + uint64_t end = log.tellg(); + EOS_ASSERT(end == pos + sizeof(header) + header.payload_size, chain::plugin_exception, + "wrote payload with incorrect size to ${name}.log", ("name", name)); + log.write((char*)&pos, sizeof(pos)); + + index.seekg(0, std::ios_base::end); + state_history_summary summary{.pos = pos}; + index.write((char*)&summary, sizeof(summary)); + if (_begin_block == _end_block) + _begin_block = header.block_num; + _end_block = header.block_num + 1; + last_block_id = header.block_id; + } + + // returns stream positioned at payload + std::fstream& get_entry(uint32_t block_num, state_history_log_header& header) { + EOS_ASSERT(block_num >= _begin_block && block_num < _end_block, chain::plugin_exception, + "read non-existing block in ${name}.log", ("name", name)); + log.seekg(get_pos(block_num)); + log.read((char*)&header, sizeof(header)); + return log; + } + + chain::block_id_type get_block_id(uint32_t block_num) { + state_history_log_header header; + get_entry(block_num, header); + return header.block_id; + } + + private: + bool get_last_block(uint64_t size) { + state_history_log_header header; + uint64_t suffix; + log.seekg(size - sizeof(suffix)); + log.read((char*)&suffix, sizeof(suffix)); + if (suffix > size || suffix + sizeof(header) > size) { + elog("corrupt ${name}.log (2)", ("name", name)); + return false; + } + log.seekg(suffix); + log.read((char*)&header, sizeof(header)); + if (suffix + sizeof(header) + header.payload_size + sizeof(suffix) != size) { + elog("corrupt ${name}.log (3)", ("name", name)); + return false; + } + _end_block = header.block_num + 1; + last_block_id = header.block_id; + if (_begin_block >= _end_block) { + elog("corrupt ${name}.log (4)", ("name", name)); + return false; + } + return true; + } + + void recover_blocks(uint64_t size) { + ilog("recover ${name}.log", ("name", name)); + uint64_t pos = 0; + uint32_t num_found = 0; + while (true) { + state_history_log_header header; + if (pos + sizeof(header) > size) + break; + log.seekg(pos); + log.read((char*)&header, sizeof(header)); + uint64_t suffix; + if (header.payload_size > size || pos + sizeof(header) + header.payload_size + sizeof(suffix) > size) + break; + log.seekg(pos + sizeof(header) + header.payload_size); + log.read((char*)&suffix, sizeof(suffix)); + if (suffix != pos) + break; + pos = pos + sizeof(header) + header.payload_size + sizeof(suffix); + if (!(++num_found % 10000)) { + printf("%10u blocks found, log pos=%12llu\r", (unsigned)num_found, (unsigned long long)pos); + fflush(stdout); + } + } + log.flush(); + boost::filesystem::resize_file(log_filename, pos); + log.sync(); + EOS_ASSERT(get_last_block(pos), chain::plugin_exception, "recover ${name}.log failed", ("name", name)); + } + + void open_log() { + log.open(log_filename, std::ios_base::binary | std::ios_base::in | std::ios_base::out | std::ios_base::app); + log.seekg(0, std::ios_base::end); + uint64_t size = log.tellg(); + if (size >= sizeof(state_history_log_header)) { + state_history_log_header header; + log.seekg(0); + log.read((char*)&header, sizeof(header)); + EOS_ASSERT(header.version == 0 && sizeof(header) + header.payload_size + sizeof(uint64_t) <= size, + chain::plugin_exception, "corrupt ${name}.log (1)", ("name", name)); + _begin_block = header.block_num; + last_block_id = header.block_id; + if (!get_last_block(size)) + recover_blocks(size); + ilog("${name}.log has blocks ${b}-${e}", ("name", name)("b", _begin_block)("e", _end_block - 1)); + } else { + EOS_ASSERT(!size, chain::plugin_exception, "corrupt ${name}.log (5)", ("name", name)); + ilog("${name}.log is empty", ("name", name)); + } + } + + void open_index() { + index.open(index_filename, std::ios_base::binary | std::ios_base::in | std::ios_base::out | std::ios_base::app); + index.seekg(0, std::ios_base::end); + if (index.tellg() == (_end_block - _begin_block) * sizeof(state_history_summary)) + return; + ilog("Regenerate ${name}.index", ("name", name)); + index.close(); + index.open(index_filename, std::ios_base::binary | std::ios_base::in | std::ios_base::out | std::ios_base::trunc); + + log.seekg(0, std::ios_base::end); + uint64_t size = log.tellg(); + uint64_t pos = 0; + uint32_t num_found = 0; + while (pos < size) { + state_history_log_header header; + EOS_ASSERT(pos + sizeof(header) <= size, chain::plugin_exception, "corrupt ${name}.log (6)", ("name", name)); + log.seekg(pos); + log.read((char*)&header, sizeof(header)); + uint64_t suffix_pos = pos + sizeof(header) + header.payload_size; + uint64_t suffix; + EOS_ASSERT(suffix_pos + sizeof(suffix) <= size, chain::plugin_exception, "corrupt ${name}.log (7)", + ("name", name)); + log.seekg(suffix_pos); + log.read((char*)&suffix, sizeof(suffix)); + // ilog("block ${b} at ${pos}-${end} suffix=${suffix} file_size=${fs}", + // ("b", header.block_num)("pos", pos)("end", suffix_pos + sizeof(suffix))("suffix", suffix)("fs", size)); + EOS_ASSERT(suffix == pos, chain::plugin_exception, "corrupt ${name}.log (8)", ("name", name)); + + state_history_summary summary{.pos = pos}; + index.write((char*)&summary, sizeof(summary)); + pos = suffix_pos + sizeof(suffix); + if (!(++num_found % 10000)) { + printf("%10u blocks found, log pos=%12llu\r", (unsigned)num_found, (unsigned long long)pos); + fflush(stdout); + } + } + } + + uint64_t get_pos(uint32_t block_num) { + state_history_summary summary; + index.seekg((block_num - _begin_block) * sizeof(summary)); + index.read((char*)&summary, sizeof(summary)); + return summary.pos; + } + + void truncate(uint32_t block_num) { + log.flush(); + index.flush(); + uint64_t num_removed = 0; + if (block_num <= _begin_block) { + num_removed = _end_block - _begin_block; + log.seekg(0); + index.seekg(0); + boost::filesystem::resize_file(log_filename, 0); + boost::filesystem::resize_file(index_filename, 0); + _begin_block = _end_block = 0; + } else { + num_removed = _end_block - block_num; + uint64_t pos = get_pos(block_num); + log.seekg(0); + index.seekg(0); + boost::filesystem::resize_file(log_filename, pos); + boost::filesystem::resize_file(index_filename, (block_num - _begin_block) * sizeof(state_history_summary)); + _end_block = block_num; + } + log.sync(); + index.sync(); + ilog("fork or replay: removed ${n} blocks from ${name}.log", ("n", num_removed)("name", name)); + } +}; // state_history_log + +} // namespace eosio diff --git a/plugins/state_history_plugin/include/eosio/state_history_plugin/state_history_plugin.hpp b/plugins/state_history_plugin/include/eosio/state_history_plugin/state_history_plugin.hpp new file mode 100644 index 0000000000000000000000000000000000000000..ce532d1c89e45191b42d9783528d92746ebd0576 --- /dev/null +++ b/plugins/state_history_plugin/include/eosio/state_history_plugin/state_history_plugin.hpp @@ -0,0 +1,101 @@ +/** + * @file + * @copyright defined in eos/LICENSE.txt + */ +#pragma once +#include + +#include + +template +struct history_serial_big_vector_wrapper { + T obj; +}; + +namespace fc { +class variant; +} + +namespace eosio { +using chain::bytes; +using std::shared_ptr; + +typedef shared_ptr state_history_ptr; + +struct table_delta { + fc::unsigned_int struct_version = 0; + std::string name{}; + history_serial_big_vector_wrapper>> rows{}; +}; + +struct block_position { + uint32_t block_num = 0; + chain::block_id_type block_id = {}; +}; + +struct get_status_request_v0 {}; + +struct get_status_result_v0 { + block_position head = {}; + block_position last_irreversible = {}; + uint32_t trace_begin_block = 0; + uint32_t trace_end_block = 0; + uint32_t chain_state_begin_block = 0; + uint32_t chain_state_end_block = 0; +}; + +struct get_blocks_request_v0 { + uint32_t start_block_num = 0; + uint32_t end_block_num = 0; + uint32_t max_messages_in_flight = 0; + std::vector have_positions = {}; + bool irreversible_only = false; + bool fetch_block = false; + bool fetch_traces = false; + bool fetch_deltas = false; +}; + +struct get_blocks_ack_request_v0 { + uint32_t num_messages = 0; +}; + +struct get_blocks_result_v0 { + block_position head; + block_position last_irreversible; + fc::optional this_block; + fc::optional prev_block; + fc::optional block; + fc::optional traces; + fc::optional deltas; +}; + +using state_request = fc::static_variant; +using state_result = fc::static_variant; + +class state_history_plugin : public plugin { + public: + APPBASE_PLUGIN_REQUIRES((chain_plugin)) + + state_history_plugin(); + virtual ~state_history_plugin(); + + virtual void set_program_options(options_description& cli, options_description& cfg) override; + + void plugin_initialize(const variables_map& options); + void plugin_startup(); + void plugin_shutdown(); + + private: + state_history_ptr my; +}; + +} // namespace eosio + +// clang-format off +FC_REFLECT(eosio::table_delta, (struct_version)(name)(rows)); +FC_REFLECT(eosio::block_position, (block_num)(block_id)); +FC_REFLECT_EMPTY(eosio::get_status_request_v0); +FC_REFLECT(eosio::get_status_result_v0, (head)(last_irreversible)(trace_begin_block)(trace_end_block)(chain_state_begin_block)(chain_state_end_block)); +FC_REFLECT(eosio::get_blocks_request_v0, (start_block_num)(end_block_num)(max_messages_in_flight)(have_positions)(irreversible_only)(fetch_block)(fetch_traces)(fetch_deltas)); +FC_REFLECT(eosio::get_blocks_ack_request_v0, (num_messages)); +// clang-format on diff --git a/plugins/state_history_plugin/include/eosio/state_history_plugin/state_history_serialization.hpp b/plugins/state_history_plugin/include/eosio/state_history_plugin/state_history_serialization.hpp new file mode 100644 index 0000000000000000000000000000000000000000..b20f264598eaf567f81e46a323bcc63888354589 --- /dev/null +++ b/plugins/state_history_plugin/include/eosio/state_history_plugin/state_history_serialization.hpp @@ -0,0 +1,547 @@ +/** + * @file + * @copyright defined in eos/LICENSE.txt + */ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +template +struct history_serial_wrapper { + const chainbase::database& db; + const T& obj; +}; + +template +history_serial_wrapper make_history_serial_wrapper(const chainbase::database& db, const T& obj) { + return {db, obj}; +} + +template +struct history_context_wrapper { + const chainbase::database& db; + const P& context; + const T& obj; +}; + +template +history_context_wrapper make_history_context_wrapper(const chainbase::database& db, P& context, const T& obj) { + return {db, context, obj}; +} + +namespace fc { + +template +const T& as_type(const T& x) { + return x; +} + +template +datastream& history_serialize_container(datastream& ds, const chainbase::database& db, const T& v) { + fc::raw::pack(ds, unsigned_int(v.size())); + for (auto& x : v) + ds << make_history_serial_wrapper(db, x); + return ds; +} + +template +datastream& history_serialize_container(datastream& ds, const chainbase::database& db, + const std::vector>& v) { + fc::raw::pack(ds, unsigned_int(v.size())); + for (auto& x : v) { + EOS_ASSERT(!!x, eosio::chain::plugin_exception, "null inside container"); + ds << make_history_serial_wrapper(db, *x); + } + return ds; +} + +template +datastream& operator<<(datastream& ds, const history_serial_big_vector_wrapper& obj) { + FC_ASSERT(obj.obj.size() <= 1024 * 1024 * 1024); + fc::raw::pack(ds, unsigned_int((uint32_t)obj.obj.size())); + for (auto& x : obj.obj) + fc::raw::pack(ds, x); + return ds; +} + +template +void history_pack_big_bytes(datastream& ds, const eosio::chain::bytes& v) { + FC_ASSERT(v.size() <= 1024 * 1024 * 1024); + fc::raw::pack(ds, unsigned_int((uint32_t)v.size())); + if (v.size()) + ds.write(&v.front(), (uint32_t)v.size()); +} + +template +void history_pack_big_bytes(datastream& ds, const fc::optional& v) { + fc::raw::pack(ds, v.valid()); + if (v) + history_pack_big_bytes(ds, *v); +} + +template +datastream& operator<<(datastream& ds, const history_serial_wrapper>& obj) { + return history_serialize_container(ds, obj.db, obj.obj); +} + +template +datastream& operator<<(datastream& ds, const history_serial_wrapper>& obj) { + fc::raw::pack(ds, obj.obj.first); + fc::raw::pack(ds, obj.obj.second); + return ds; +} + +template +datastream& operator<<(datastream& ds, const history_serial_wrapper& obj) { + fc::raw::pack(ds, fc::unsigned_int(0)); + fc::raw::pack(ds, as_type(obj.obj.name.value)); + fc::raw::pack(ds, as_type(obj.obj.vm_type)); + fc::raw::pack(ds, as_type(obj.obj.vm_version)); + fc::raw::pack(ds, as_type(obj.obj.privileged)); + fc::raw::pack(ds, as_type(obj.obj.last_code_update)); + fc::raw::pack(ds, as_type(obj.obj.code_version)); + fc::raw::pack(ds, as_type(obj.obj.creation_date)); + fc::raw::pack(ds, as_type(obj.obj.code)); + fc::raw::pack(ds, as_type(obj.obj.abi)); + return ds; +} + +template +datastream& operator<<(datastream& ds, const history_serial_wrapper& obj) { + fc::raw::pack(ds, fc::unsigned_int(0)); + fc::raw::pack(ds, as_type(obj.obj.code.value)); + fc::raw::pack(ds, as_type(obj.obj.scope.value)); + fc::raw::pack(ds, as_type(obj.obj.table.value)); + fc::raw::pack(ds, as_type(obj.obj.payer.value)); + return ds; +} + +template +datastream& +operator<<(datastream& ds, + const history_context_wrapper& obj) { + fc::raw::pack(ds, fc::unsigned_int(0)); + fc::raw::pack(ds, as_type(obj.context.code.value)); + fc::raw::pack(ds, as_type(obj.context.scope.value)); + fc::raw::pack(ds, as_type(obj.context.table.value)); + fc::raw::pack(ds, as_type(obj.obj.primary_key)); + fc::raw::pack(ds, as_type(obj.obj.payer.value)); + fc::raw::pack(ds, as_type(obj.obj.value)); + return ds; +} + +template +void serialize_secondary_index_data(datastream& ds, const T& obj) { + fc::raw::pack(ds, obj); +} + +template +void serialize_secondary_index_data(datastream& ds, const float64_t& obj) { + uint64_t i; + memcpy(&i, &obj, sizeof(i)); + fc::raw::pack(ds, i); +} + +template +void serialize_secondary_index_data(datastream& ds, const float128_t& obj) { + __uint128_t i; + memcpy(&i, &obj, sizeof(i)); + fc::raw::pack(ds, i); +} + +template +void serialize_secondary_index_data(datastream& ds, const eosio::chain::key256_t& obj) { + auto rev = [&](__uint128_t x) { + char* ch = reinterpret_cast(&x); + std::reverse(ch, ch + sizeof(x)); + return x; + }; + fc::raw::pack(ds, rev(obj[0])); + fc::raw::pack(ds, rev(obj[1])); +} + +template +datastream& serialize_secondary_index(datastream& ds, const eosio::chain::table_id_object& context, + const T& obj) { + fc::raw::pack(ds, fc::unsigned_int(0)); + fc::raw::pack(ds, as_type(context.code.value)); + fc::raw::pack(ds, as_type(context.scope.value)); + fc::raw::pack(ds, as_type(context.table.value)); + fc::raw::pack(ds, as_type(obj.primary_key)); + fc::raw::pack(ds, as_type(obj.payer.value)); + serialize_secondary_index_data(ds, obj.secondary_key); + return ds; +} + +template +datastream& +operator<<(datastream& ds, + const history_context_wrapper& obj) { + return serialize_secondary_index(ds, obj.context, obj.obj); +} + +template +datastream& +operator<<(datastream& ds, + const history_context_wrapper& obj) { + return serialize_secondary_index(ds, obj.context, obj.obj); +} + +template +datastream& +operator<<(datastream& ds, + const history_context_wrapper& obj) { + return serialize_secondary_index(ds, obj.context, obj.obj); +} + +template +datastream& +operator<<(datastream& ds, + const history_context_wrapper& obj) { + return serialize_secondary_index(ds, obj.context, obj.obj); +} + +template +datastream& operator<<( + datastream& ds, + const history_context_wrapper& obj) { + return serialize_secondary_index(ds, obj.context, obj.obj); +} + +template +datastream& operator<<(datastream& ds, const history_serial_wrapper& obj) { + fc::raw::pack(ds, as_type(obj.obj.producer_name.value)); + fc::raw::pack(ds, as_type(obj.obj.block_signing_key)); + return ds; +} + +template +datastream& operator<<(datastream& ds, + const history_serial_wrapper& obj) { + fc::raw::pack(ds, as_type(obj.obj.version)); + history_serialize_container(ds, obj.db, + as_type>(obj.obj.producers)); + return ds; +} + +template +datastream& operator<<(datastream& ds, const history_serial_wrapper& obj) { + fc::raw::pack(ds, fc::unsigned_int(0)); + fc::raw::pack(ds, as_type(obj.obj.max_block_net_usage)); + fc::raw::pack(ds, as_type(obj.obj.target_block_net_usage_pct)); + fc::raw::pack(ds, as_type(obj.obj.max_transaction_net_usage)); + fc::raw::pack(ds, as_type(obj.obj.base_per_transaction_net_usage)); + fc::raw::pack(ds, as_type(obj.obj.net_usage_leeway)); + fc::raw::pack(ds, as_type(obj.obj.context_free_discount_net_usage_num)); + fc::raw::pack(ds, as_type(obj.obj.context_free_discount_net_usage_den)); + fc::raw::pack(ds, as_type(obj.obj.max_block_cpu_usage)); + fc::raw::pack(ds, as_type(obj.obj.target_block_cpu_usage_pct)); + fc::raw::pack(ds, as_type(obj.obj.max_transaction_cpu_usage)); + fc::raw::pack(ds, as_type(obj.obj.min_transaction_cpu_usage)); + fc::raw::pack(ds, as_type(obj.obj.max_transaction_lifetime)); + fc::raw::pack(ds, as_type(obj.obj.deferred_trx_expiration_window)); + fc::raw::pack(ds, as_type(obj.obj.max_transaction_delay)); + fc::raw::pack(ds, as_type(obj.obj.max_inline_action_size)); + fc::raw::pack(ds, as_type(obj.obj.max_inline_action_depth)); + fc::raw::pack(ds, as_type(obj.obj.max_authority_depth)); + return ds; +} + +template +datastream& operator<<(datastream& ds, + const history_serial_wrapper& obj) { + fc::raw::pack(ds, fc::unsigned_int(0)); + fc::raw::pack(ds, as_type>(obj.obj.proposed_schedule_block_num)); + fc::raw::pack(ds, make_history_serial_wrapper( + obj.db, as_type(obj.obj.proposed_schedule))); + fc::raw::pack(ds, make_history_serial_wrapper(obj.db, as_type(obj.obj.configuration))); + + return ds; +} + +template +datastream& operator<<(datastream& ds, + const history_serial_wrapper& obj) { + fc::raw::pack(ds, fc::unsigned_int(0)); + fc::raw::pack(ds, as_type(obj.obj.sender.value)); + fc::raw::pack(ds, as_type<__uint128_t>(obj.obj.sender_id)); + fc::raw::pack(ds, as_type(obj.obj.payer.value)); + fc::raw::pack(ds, as_type(obj.obj.trx_id)); + fc::raw::pack(ds, as_type(obj.obj.packed_trx)); + return ds; +} + +template +datastream& operator<<(datastream& ds, const history_serial_wrapper& obj) { + fc::raw::pack(ds, as_type(obj.obj.key)); + fc::raw::pack(ds, as_type(obj.obj.weight)); + return ds; +} + +template +datastream& operator<<(datastream& ds, const history_serial_wrapper& obj) { + fc::raw::pack(ds, as_type(obj.obj.actor.value)); + fc::raw::pack(ds, as_type(obj.obj.permission.value)); + return ds; +} + +template +datastream& operator<<(datastream& ds, + const history_serial_wrapper& obj) { + fc::raw::pack(ds, make_history_serial_wrapper(obj.db, as_type(obj.obj.permission))); + fc::raw::pack(ds, as_type(obj.obj.weight)); + return ds; +} + +template +datastream& operator<<(datastream& ds, const history_serial_wrapper& obj) { + fc::raw::pack(ds, as_type(obj.obj.wait_sec)); + fc::raw::pack(ds, as_type(obj.obj.weight)); + return ds; +} + +template +datastream& operator<<(datastream& ds, const history_serial_wrapper& obj) { + fc::raw::pack(ds, as_type(obj.obj.threshold)); + history_serialize_container(ds, obj.db, obj.obj.keys); + history_serialize_container(ds, obj.db, obj.obj.accounts); + history_serialize_container(ds, obj.db, obj.obj.waits); + return ds; +} + +template +datastream& operator<<(datastream& ds, const history_serial_wrapper& obj) { + fc::raw::pack(ds, fc::unsigned_int(0)); + fc::raw::pack(ds, as_type(obj.obj.owner.value)); + fc::raw::pack(ds, as_type(obj.obj.name.value)); + if (obj.obj.parent._id) + fc::raw::pack(ds, as_type(obj.db.get(obj.obj.parent).name.value)); + else + fc::raw::pack(ds, as_type(0)); + fc::raw::pack(ds, as_type(obj.obj.last_updated)); + fc::raw::pack(ds, make_history_serial_wrapper(obj.db, as_type(obj.obj.auth))); + return ds; +} + +template +datastream& operator<<(datastream& ds, + const history_serial_wrapper& obj) { + fc::raw::pack(ds, fc::unsigned_int(0)); + fc::raw::pack(ds, as_type(obj.obj.account.value)); + fc::raw::pack(ds, as_type(obj.obj.code.value)); + fc::raw::pack(ds, as_type(obj.obj.message_type.value)); + fc::raw::pack(ds, as_type(obj.obj.required_permission.value)); + return ds; +} + +template +datastream& operator<<(datastream& ds, + const history_serial_wrapper& obj) { + EOS_ASSERT(!obj.obj.pending, eosio::chain::plugin_exception, + "accepted_block sent while resource_limits_object in pending state"); + fc::raw::pack(ds, fc::unsigned_int(0)); + fc::raw::pack(ds, as_type(obj.obj.owner.value)); + fc::raw::pack(ds, as_type(obj.obj.net_weight)); + fc::raw::pack(ds, as_type(obj.obj.cpu_weight)); + fc::raw::pack(ds, as_type(obj.obj.ram_bytes)); + return ds; +} + +template +datastream& operator<<(datastream& ds, + const history_serial_wrapper& obj) { + fc::raw::pack(ds, fc::unsigned_int(0)); + fc::raw::pack(ds, as_type(obj.obj.last_ordinal)); + fc::raw::pack(ds, as_type(obj.obj.value_ex)); + fc::raw::pack(ds, as_type(obj.obj.consumed)); + return ds; +} + +template +datastream& operator<<(datastream& ds, + const history_serial_wrapper& obj) { + fc::raw::pack(ds, fc::unsigned_int(0)); + fc::raw::pack(ds, as_type(obj.obj.owner.value)); + fc::raw::pack(ds, make_history_serial_wrapper( + obj.db, as_type(obj.obj.net_usage))); + fc::raw::pack(ds, make_history_serial_wrapper( + obj.db, as_type(obj.obj.cpu_usage))); + fc::raw::pack(ds, as_type(obj.obj.ram_usage)); + return ds; +} + +template +datastream& +operator<<(datastream& ds, + const history_serial_wrapper& obj) { + fc::raw::pack(ds, fc::unsigned_int(0)); + fc::raw::pack(ds, make_history_serial_wrapper(obj.db, as_type( + obj.obj.average_block_net_usage))); + fc::raw::pack(ds, make_history_serial_wrapper(obj.db, as_type( + obj.obj.average_block_cpu_usage))); + fc::raw::pack(ds, as_type(obj.obj.total_net_weight)); + fc::raw::pack(ds, as_type(obj.obj.total_cpu_weight)); + fc::raw::pack(ds, as_type(obj.obj.total_ram_bytes)); + fc::raw::pack(ds, as_type(obj.obj.virtual_net_limit)); + fc::raw::pack(ds, as_type(obj.obj.virtual_cpu_limit)); + return ds; +} + +template +datastream& operator<<(datastream& ds, + const history_serial_wrapper& obj) { + fc::raw::pack(ds, fc::unsigned_int(0)); + fc::raw::pack(ds, as_type(obj.obj.numerator)); + fc::raw::pack(ds, as_type(obj.obj.denominator)); + return ds; +} + +template +datastream& operator<<(datastream& ds, + const history_serial_wrapper& obj) { + fc::raw::pack(ds, fc::unsigned_int(0)); + fc::raw::pack(ds, as_type(obj.obj.target)); + fc::raw::pack(ds, as_type(obj.obj.max)); + fc::raw::pack(ds, as_type(obj.obj.periods)); + fc::raw::pack(ds, as_type(obj.obj.max_multiplier)); + fc::raw::pack( + ds, make_history_serial_wrapper(obj.db, as_type(obj.obj.contract_rate))); + fc::raw::pack( + ds, make_history_serial_wrapper(obj.db, as_type(obj.obj.expand_rate))); + return ds; +} + +template +datastream& +operator<<(datastream& ds, + const history_serial_wrapper& obj) { + fc::raw::pack(ds, fc::unsigned_int(0)); + fc::raw::pack( + ds, make_history_serial_wrapper( + obj.db, as_type(obj.obj.cpu_limit_parameters))); + fc::raw::pack( + ds, make_history_serial_wrapper( + obj.db, as_type(obj.obj.net_limit_parameters))); + fc::raw::pack(ds, as_type(obj.obj.account_cpu_usage_average_window)); + fc::raw::pack(ds, as_type(obj.obj.account_net_usage_average_window)); + return ds; +}; + +template +datastream& operator<<(datastream& ds, const history_serial_wrapper& obj) { + fc::raw::pack(ds, as_type(obj.obj.account.value)); + fc::raw::pack(ds, as_type(obj.obj.name.value)); + history_serialize_container(ds, obj.db, as_type>(obj.obj.authorization)); + fc::raw::pack(ds, as_type(obj.obj.data)); + return ds; +} + +template +datastream& operator<<(datastream& ds, const history_serial_wrapper& obj) { + fc::raw::pack(ds, fc::unsigned_int(0)); + fc::raw::pack(ds, as_type(obj.obj.receiver.value)); + fc::raw::pack(ds, as_type(obj.obj.act_digest)); + fc::raw::pack(ds, as_type(obj.obj.global_sequence)); + fc::raw::pack(ds, as_type(obj.obj.recv_sequence)); + history_serialize_container(ds, obj.db, as_type>(obj.obj.auth_sequence)); + fc::raw::pack(ds, as_type(obj.obj.code_sequence)); + fc::raw::pack(ds, as_type(obj.obj.abi_sequence)); + return ds; +} + +template +datastream& operator<<(datastream& ds, const history_serial_wrapper& obj) { + fc::raw::pack(ds, as_type(obj.obj.account.value)); + fc::raw::pack(ds, as_type(obj.obj.delta)); + return ds; +} + +template +datastream& operator<<(datastream& ds, const history_serial_wrapper& obj) { + fc::raw::pack(ds, fc::unsigned_int(0)); + fc::raw::pack(ds, make_history_serial_wrapper(obj.db, as_type(obj.obj.receipt))); + fc::raw::pack(ds, make_history_serial_wrapper(obj.db, as_type(obj.obj.act))); + fc::raw::pack(ds, as_type(obj.obj.context_free)); + fc::raw::pack(ds, as_type(obj.obj.elapsed.count())); + fc::raw::pack(ds, as_type(obj.obj.console)); + history_serialize_container(ds, obj.db, as_type>(obj.obj.account_ram_deltas)); + + fc::optional e; + if (obj.obj.except) + e = obj.obj.except->to_string(); + fc::raw::pack(ds, as_type>(e)); + + history_serialize_container(ds, obj.db, as_type>(obj.obj.inline_traces)); + return ds; +} + +template +datastream& operator<<(datastream& ds, + const history_context_wrapper& obj) { + fc::raw::pack(ds, fc::unsigned_int(0)); + fc::raw::pack(ds, as_type(obj.obj.id)); + if (obj.obj.receipt) { + if (obj.obj.failed_dtrx_trace && + obj.obj.receipt->status.value == eosio::chain::transaction_receipt_header::soft_fail) + fc::raw::pack(ds, uint8_t(eosio::chain::transaction_receipt_header::executed)); + else + fc::raw::pack(ds, as_type(obj.obj.receipt->status.value)); + fc::raw::pack(ds, as_type(obj.obj.receipt->cpu_usage_us)); + fc::raw::pack(ds, as_type(obj.obj.receipt->net_usage_words)); + } else { + fc::raw::pack(ds, uint8_t(obj.context)); + fc::raw::pack(ds, uint32_t(0)); + fc::raw::pack(ds, fc::unsigned_int(0)); + } + fc::raw::pack(ds, as_type(obj.obj.elapsed.count())); + fc::raw::pack(ds, as_type(obj.obj.net_usage)); + fc::raw::pack(ds, as_type(obj.obj.scheduled)); + history_serialize_container(ds, obj.db, as_type>(obj.obj.action_traces)); + + fc::optional e; + if (obj.obj.except) + e = obj.obj.except->to_string(); + fc::raw::pack(ds, as_type>(e)); + + fc::raw::pack(ds, bool(obj.obj.failed_dtrx_trace)); + if (obj.obj.failed_dtrx_trace) { + uint8_t stat = eosio::chain::transaction_receipt_header::hard_fail; + if (obj.obj.receipt && obj.obj.receipt->status.value == eosio::chain::transaction_receipt_header::soft_fail) + stat = eosio::chain::transaction_receipt_header::soft_fail; + fc::raw::pack(ds, make_history_context_wrapper(obj.db, stat, *obj.obj.failed_dtrx_trace)); + } + + return ds; +} + +template +datastream& operator<<(datastream& ds, const history_serial_wrapper& obj) { + uint8_t stat = eosio::chain::transaction_receipt_header::hard_fail; + ds << make_history_context_wrapper(obj.db, stat, obj.obj); + return ds; +} + +template +datastream& operator<<(datastream& ds, const eosio::get_blocks_result_v0& obj) { + fc::raw::pack(ds, obj.head); + fc::raw::pack(ds, obj.last_irreversible); + fc::raw::pack(ds, obj.this_block); + fc::raw::pack(ds, obj.prev_block); + history_pack_big_bytes(ds, obj.block); + history_pack_big_bytes(ds, obj.traces); + history_pack_big_bytes(ds, obj.deltas); + return ds; +} + +} // namespace fc diff --git a/plugins/state_history_plugin/state_history_plugin.cpp b/plugins/state_history_plugin/state_history_plugin.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e625af5052a3b61e95ba82e55b708f351837690c --- /dev/null +++ b/plugins/state_history_plugin/state_history_plugin.cpp @@ -0,0 +1,571 @@ +/** + * @file + * @copyright defined in eos/LICENSE.txt + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using tcp = boost::asio::ip::tcp; +namespace ws = boost::beast::websocket; + +extern const char* const state_history_plugin_abi; + +namespace eosio { +using namespace chain; +using boost::signals2::scoped_connection; + +static appbase::abstract_plugin& _state_history_plugin = app().register_plugin(); + +template +auto catch_and_log(F f) { + try { + return f(); + } catch (const fc::exception& e) { + elog("${e}", ("e", e.to_detail_string())); + } catch (const std::exception& e) { + elog("${e}", ("e", e.what())); + } catch (...) { + elog("unknown exception"); + } +} + +namespace bio = boost::iostreams; +static bytes zlib_compress_bytes(bytes in) { + bytes out; + bio::filtering_ostream comp; + comp.push(bio::zlib_compressor(bio::zlib::default_compression)); + comp.push(bio::back_inserter(out)); + bio::write(comp, in.data(), in.size()); + bio::close(comp); + return out; +} + +struct state_history_plugin_impl : std::enable_shared_from_this { + chain_plugin* chain_plug = nullptr; + fc::optional trace_log; + fc::optional chain_state_log; + bool stopping = false; + fc::optional applied_transaction_connection; + fc::optional accepted_block_connection; + string endpoint_address = "0.0.0.0"; + uint16_t endpoint_port = 8080; + std::unique_ptr acceptor; + std::map cached_traces; + transaction_trace_ptr onblock_trace; + + void get_log_entry(state_history_log& log, uint32_t block_num, fc::optional& result) { + if (block_num < log.begin_block() || block_num >= log.end_block()) + return; + state_history_log_header header; + auto& stream = log.get_entry(block_num, header); + uint32_t s; + stream.read((char*)&s, sizeof(s)); + result.emplace(); + result->resize(s); + if (s) + stream.read(result->data(), s); + } + + void get_block(uint32_t block_num, fc::optional& result) { + chain::signed_block_ptr p; + try { + p = chain_plug->chain().fetch_block_by_number(block_num); + } catch (...) { + return; + } + result = fc::raw::pack(*p); + } + + fc::optional get_block_id(uint32_t block_num) { + if (trace_log && block_num >= trace_log->begin_block() && block_num < trace_log->end_block()) + return trace_log->get_block_id(block_num); + if (chain_state_log && block_num >= chain_state_log->begin_block() && block_num < chain_state_log->end_block()) + return chain_state_log->get_block_id(block_num); + try { + auto block = chain_plug->chain().fetch_block_by_number(block_num); + if (block) + return block->id(); + } catch (...) { + } + return {}; + } + + struct session : std::enable_shared_from_this { + std::shared_ptr plugin; + std::unique_ptr> socket_stream; + bool sending = false; + bool sent_abi = false; + std::vector> send_queue; + fc::optional current_request; + bool need_to_send_update = false; + + session(std::shared_ptr plugin) + : plugin(std::move(plugin)) {} + + void start(tcp::socket socket) { + ilog("incoming connection"); + socket_stream = std::make_unique>(std::move(socket)); + socket_stream->binary(true); + socket_stream->next_layer().set_option(boost::asio::ip::tcp::no_delay(true)); + socket_stream->next_layer().set_option(boost::asio::socket_base::send_buffer_size(1024 * 1024)); + socket_stream->next_layer().set_option(boost::asio::socket_base::receive_buffer_size(1024 * 1024)); + socket_stream->async_accept([self = shared_from_this(), this](boost::system::error_code ec) { + callback(ec, "async_accept", [&] { + start_read(); + send(state_history_plugin_abi); + }); + }); + } + + void start_read() { + auto in_buffer = std::make_shared(); + socket_stream->async_read( + *in_buffer, [self = shared_from_this(), this, in_buffer](boost::system::error_code ec, size_t) { + callback(ec, "async_read", [&] { + auto d = boost::asio::buffer_cast(boost::beast::buffers_front(in_buffer->data())); + auto s = boost::asio::buffer_size(in_buffer->data()); + fc::datastream ds(d, s); + state_request req; + fc::raw::unpack(ds, req); + req.visit(*this); + start_read(); + }); + }); + } + + void send(const char* s) { + send_queue.push_back({s, s + strlen(s)}); + send(); + } + + template + void send(T obj) { + send_queue.push_back(fc::raw::pack(state_result{std::move(obj)})); + send(); + } + + void send() { + if (sending) + return; + if (send_queue.empty()) + return send_update(); + sending = true; + socket_stream->binary(sent_abi); + sent_abi = true; + socket_stream->async_write( // + boost::asio::buffer(send_queue[0]), + [self = shared_from_this(), this](boost::system::error_code ec, size_t) { + callback(ec, "async_write", [&] { + send_queue.erase(send_queue.begin()); + sending = false; + send(); + }); + }); + } + + using result_type = void; + void operator()(get_status_request_v0&) { + auto& chain = plugin->chain_plug->chain(); + get_status_result_v0 result; + result.head = {chain.head_block_num(), chain.head_block_id()}; + result.last_irreversible = {chain.last_irreversible_block_num(), chain.last_irreversible_block_id()}; + if (plugin->trace_log) { + result.trace_begin_block = plugin->trace_log->begin_block(); + result.trace_end_block = plugin->trace_log->end_block(); + } + if (plugin->chain_state_log) { + result.chain_state_begin_block = plugin->chain_state_log->begin_block(); + result.chain_state_end_block = plugin->chain_state_log->end_block(); + } + send(std::move(result)); + } + + void operator()(get_blocks_request_v0& req) { + for (auto& cp : req.have_positions) { + if (req.start_block_num <= cp.block_num) + continue; + auto id = plugin->get_block_id(cp.block_num); + if (!id || *id != cp.block_id) + req.start_block_num = std::min(req.start_block_num, cp.block_num); + } + req.have_positions.clear(); + current_request = req; + send_update(true); + } + + void operator()(get_blocks_ack_request_v0& req) { + if (!current_request) + return; + current_request->max_messages_in_flight += req.num_messages; + send_update(); + } + + void send_update(bool changed = false) { + if (changed) + need_to_send_update = true; + if (!send_queue.empty() || !need_to_send_update || !current_request || + !current_request->max_messages_in_flight) + return; + auto& chain = plugin->chain_plug->chain(); + get_blocks_result_v0 result; + result.head = {chain.head_block_num(), chain.head_block_id()}; + result.last_irreversible = {chain.last_irreversible_block_num(), chain.last_irreversible_block_id()}; + uint32_t current = + current_request->irreversible_only ? result.last_irreversible.block_num : result.head.block_num; + if (current_request->start_block_num <= current && + current_request->start_block_num < current_request->end_block_num) { + auto block_id = plugin->get_block_id(current_request->start_block_num); + if (block_id) { + result.this_block = block_position{current_request->start_block_num, *block_id}; + auto prev_block_id = plugin->get_block_id(current_request->start_block_num - 1); + if (prev_block_id) + result.prev_block = block_position{current_request->start_block_num - 1, *prev_block_id}; + if (current_request->fetch_block) + plugin->get_block(current_request->start_block_num, result.block); + if (current_request->fetch_traces && plugin->trace_log) + plugin->get_log_entry(*plugin->trace_log, current_request->start_block_num, result.traces); + if (current_request->fetch_deltas && plugin->chain_state_log) + plugin->get_log_entry(*plugin->chain_state_log, current_request->start_block_num, result.deltas); + } + ++current_request->start_block_num; + } + send(std::move(result)); + --current_request->max_messages_in_flight; + need_to_send_update = current_request->start_block_num <= current && + current_request->start_block_num < current_request->end_block_num; + } + + template + void catch_and_close(F f) { + try { + f(); + } catch (const fc::exception& e) { + elog("${e}", ("e", e.to_detail_string())); + close(); + } catch (const std::exception& e) { + elog("${e}", ("e", e.what())); + close(); + } catch (...) { + elog("unknown exception"); + close(); + } + } + + template + void callback(boost::system::error_code ec, const char* what, F f) { + if (plugin->stopping) + return; + if (ec) + return on_fail(ec, what); + catch_and_close(f); + } + + void on_fail(boost::system::error_code ec, const char* what) { + try { + elog("${w}: ${m}", ("w", what)("m", ec.message())); + close(); + } catch (...) { + elog("uncaught exception on close"); + } + } + + void close() { + socket_stream->next_layer().close(); + plugin->sessions.erase(this); + } + }; + std::map> sessions; + + void listen() { + boost::system::error_code ec; + + auto address = boost::asio::ip::make_address(endpoint_address); + auto endpoint = tcp::endpoint{address, endpoint_port}; + acceptor = std::make_unique(app().get_io_service()); + + auto check_ec = [&](const char* what) { + if (!ec) + return; + elog("${w}: ${m}", ("w", what)("m", ec.message())); + EOS_ASSERT(false, plugin_exception, "unable to open listen socket"); + }; + + acceptor->open(endpoint.protocol(), ec); + check_ec("open"); + acceptor->set_option(boost::asio::socket_base::reuse_address(true)); + acceptor->bind(endpoint, ec); + check_ec("bind"); + acceptor->listen(boost::asio::socket_base::max_listen_connections, ec); + check_ec("listen"); + do_accept(); + } + + void do_accept() { + auto socket = std::make_shared(app().get_io_service()); + acceptor->async_accept(*socket, [self = shared_from_this(), socket, this](auto ec) { + if (stopping) + return; + if (ec) { + if (ec == boost::system::errc::too_many_files_open) + catch_and_log([&] { do_accept(); }); + return; + } + catch_and_log([&] { + auto s = std::make_shared(self); + sessions[s.get()] = s; + s->start(std::move(*socket)); + }); + catch_and_log([&] { do_accept(); }); + }); + } + + static bool is_onblock(const transaction_trace_ptr& p) { + if (p->action_traces.size() != 1) + return false; + auto& act = p->action_traces[0].act; + if (act.account != eosio::chain::config::system_account_name || act.name != N(onblock) || + act.authorization.size() != 1) + return false; + auto& auth = act.authorization[0]; + return auth.actor == eosio::chain::config::system_account_name && + auth.permission == eosio::chain::config::active_name; + } + + void on_applied_transaction(const transaction_trace_ptr& p) { + if (p->receipt) { + if (is_onblock(p)) + onblock_trace = p; + else if (p->failed_dtrx_trace) + cached_traces[p->failed_dtrx_trace->id] = p; + else + cached_traces[p->id] = p; + } + } + + void on_accepted_block(const block_state_ptr& block_state) { + store_traces(block_state); + store_chain_state(block_state); + for (auto& s : sessions) { + auto& p = s.second; + if (p) { + if (p->current_request && block_state->block_num < p->current_request->start_block_num) + p->current_request->start_block_num = block_state->block_num; + p->send_update(true); + } + } + } + + void store_traces(const block_state_ptr& block_state) { + if (!trace_log) + return; + std::vector traces; + if (onblock_trace) + traces.push_back(onblock_trace); + for (auto& r : block_state->block->transactions) { + transaction_id_type id; + if (r.trx.contains()) + id = r.trx.get(); + else + id = r.trx.get().id(); + auto it = cached_traces.find(id); + EOS_ASSERT(it != cached_traces.end() && it->second->receipt, plugin_exception, + "missing trace for transaction ${id}", ("id", id)); + traces.push_back(it->second); + } + cached_traces.clear(); + onblock_trace.reset(); + + auto& db = chain_plug->chain().db(); + auto traces_bin = zlib_compress_bytes(fc::raw::pack(make_history_serial_wrapper(db, traces))); + EOS_ASSERT(traces_bin.size() == (uint32_t)traces_bin.size(), plugin_exception, "traces is too big"); + + state_history_log_header header{.block_num = block_state->block->block_num(), + .block_id = block_state->block->id(), + .payload_size = sizeof(uint32_t) + traces_bin.size()}; + trace_log->write_entry(header, block_state->block->previous, [&](auto& stream) { + uint32_t s = (uint32_t)traces_bin.size(); + stream.write((char*)&s, sizeof(s)); + if (!traces_bin.empty()) + stream.write(traces_bin.data(), traces_bin.size()); + }); + } + + void store_chain_state(const block_state_ptr& block_state) { + if (!chain_state_log) + return; + bool fresh = chain_state_log->begin_block() == chain_state_log->end_block(); + if (fresh) + ilog("Placing initial state in block ${n}", ("n", block_state->block->block_num())); + + std::vector deltas; + auto& db = chain_plug->chain().db(); + + const auto& table_id_index = db.get_index(); + std::map removed_table_id; + for (auto& rem : table_id_index.stack().back().removed_values) + removed_table_id[rem.first._id] = &rem.second; + + auto get_table_id = [&](uint64_t tid) -> const table_id_object& { + auto obj = table_id_index.find(tid); + if (obj) + return *obj; + auto it = removed_table_id.find(tid); + EOS_ASSERT(it != removed_table_id.end(), chain::plugin_exception, "can not found table id ${tid}", + ("tid", tid)); + return *it->second; + }; + + auto pack_row = [&](auto& row) { return fc::raw::pack(make_history_serial_wrapper(db, row)); }; + auto pack_contract_row = [&](auto& row) { + return fc::raw::pack(make_history_context_wrapper(db, get_table_id(row.t_id._id), row)); + }; + + auto process_table = [&](auto* name, auto& index, auto& pack_row) { + if (fresh) { + if (index.indices().empty()) + return; + deltas.push_back({}); + auto& delta = deltas.back(); + delta.name = name; + for (auto& row : index.indices()) + delta.rows.obj.emplace_back(true, pack_row(row)); + } else { + if (index.stack().empty()) + return; + auto& undo = index.stack().back(); + if (undo.old_values.empty() && undo.new_ids.empty() && undo.removed_values.empty()) + return; + deltas.push_back({}); + auto& delta = deltas.back(); + delta.name = name; + for (auto& old : undo.old_values) { + auto& row = index.get(old.first); + delta.rows.obj.emplace_back(true, pack_row(row)); + } + for (auto& old : undo.removed_values) + delta.rows.obj.emplace_back(false, pack_row(old.second)); + for (auto id : undo.new_ids) { + auto& row = index.get(id); + delta.rows.obj.emplace_back(true, pack_row(row)); + } + } + }; + + process_table("account", db.get_index(), pack_row); + + process_table("contract_table", db.get_index(), pack_row); + process_table("contract_row", db.get_index(), pack_contract_row); + process_table("contract_index64", db.get_index(), pack_contract_row); + process_table("contract_index128", db.get_index(), pack_contract_row); + process_table("contract_index256", db.get_index(), pack_contract_row); + process_table("contract_index_double", db.get_index(), pack_contract_row); + process_table("contract_index_long_double", db.get_index(), pack_contract_row); + + process_table("global_property", db.get_index(), pack_row); + process_table("generated_transaction", db.get_index(), pack_row); + + process_table("permission", db.get_index(), pack_row); + process_table("permission_link", db.get_index(), pack_row); + + process_table("resource_limits", db.get_index(), pack_row); + process_table("resource_usage", db.get_index(), pack_row); + process_table("resource_limits_state", db.get_index(), pack_row); + process_table("resource_limits_config", db.get_index(), pack_row); + + auto deltas_bin = zlib_compress_bytes(fc::raw::pack(deltas)); + EOS_ASSERT(deltas_bin.size() == (uint32_t)deltas_bin.size(), plugin_exception, "deltas is too big"); + state_history_log_header header{.block_num = block_state->block->block_num(), + .block_id = block_state->block->id(), + .payload_size = sizeof(uint32_t) + deltas_bin.size()}; + chain_state_log->write_entry(header, block_state->block->previous, [&](auto& stream) { + uint32_t s = (uint32_t)deltas_bin.size(); + stream.write((char*)&s, sizeof(s)); + if (!deltas_bin.empty()) + stream.write(deltas_bin.data(), deltas_bin.size()); + }); + } // store_chain_state +}; // state_history_plugin_impl + +state_history_plugin::state_history_plugin() + : my(std::make_shared()) {} + +state_history_plugin::~state_history_plugin() {} + +void state_history_plugin::set_program_options(options_description& cli, options_description& cfg) { + auto options = cfg.add_options(); + options("state-history-dir", bpo::value()->default_value("state-history"), + "the location of the state-history directory (absolute path or relative to application data dir)"); + cli.add_options()("delete-state-history", bpo::bool_switch()->default_value(false), "clear state history files"); + options("trace-history", bpo::bool_switch()->default_value(false), "enable trace history"); + options("chain-state-history", bpo::bool_switch()->default_value(false), "enable chain state history"); + options("state-history-endpoint", bpo::value()->default_value("0.0.0.0:8080"), + "the endpoint upon which to listen for incoming connections"); +} + +void state_history_plugin::plugin_initialize(const variables_map& options) { + try { + EOS_ASSERT(options.at("disable-replay-opts").as(), plugin_exception, + "state_history_plugin requires --disable-replay-opts"); + + my->chain_plug = app().find_plugin(); + EOS_ASSERT(my->chain_plug, chain::missing_chain_plugin_exception, ""); + auto& chain = my->chain_plug->chain(); + my->applied_transaction_connection.emplace( + chain.applied_transaction.connect([&](const transaction_trace_ptr& p) { my->on_applied_transaction(p); })); + my->accepted_block_connection.emplace( + chain.accepted_block.connect([&](const block_state_ptr& p) { my->on_accepted_block(p); })); + + auto dir_option = options.at("state-history-dir").as(); + boost::filesystem::path state_history_dir; + if (dir_option.is_relative()) + state_history_dir = app().data_dir() / dir_option; + else + state_history_dir = dir_option; + + auto ip_port = options.at("state-history-endpoint").as(); + auto port = ip_port.substr(ip_port.find(':') + 1, ip_port.size()); + auto host = ip_port.substr(0, ip_port.find(':')); + my->endpoint_address = host; + my->endpoint_port = std::stoi(port); + idump((ip_port)(host)(port)); + + if (options.at("delete-state-history").as()) { + ilog("Deleting state history"); + boost::filesystem::remove_all(state_history_dir); + } + boost::filesystem::create_directories(state_history_dir); + + if (options.at("trace-history").as()) + my->trace_log.emplace("trace_history", (state_history_dir / "trace_history.log").string(), + (state_history_dir / "trace_history.index").string()); + if (options.at("chain-state-history").as()) + my->chain_state_log.emplace("chain_state_history", (state_history_dir / "chain_state_history.log").string(), + (state_history_dir / "chain_state_history.index").string()); + } + FC_LOG_AND_RETHROW() +} // state_history_plugin::plugin_initialize + +void state_history_plugin::plugin_startup() { my->listen(); } + +void state_history_plugin::plugin_shutdown() { + my->applied_transaction_connection.reset(); + my->accepted_block_connection.reset(); + while (!my->sessions.empty()) + my->sessions.begin()->second->close(); + my->stopping = true; +} + +} // namespace eosio diff --git a/plugins/state_history_plugin/state_history_plugin_abi.cpp b/plugins/state_history_plugin/state_history_plugin_abi.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bdedcc81cd9405c3ffeaf9b8e5e63c8c929ab41b --- /dev/null +++ b/plugins/state_history_plugin/state_history_plugin_abi.cpp @@ -0,0 +1,475 @@ +extern const char* const state_history_plugin_abi = R"({ + "version": "eosio::abi/1.1", + "structs": [ + { + "name": "get_status_request_v0", "fields": [] + }, + { + "name": "block_position", "fields": [ + { "name": "block_num", "type": "uint32" }, + { "name": "block_id", "type": "checksum256" } + ] + }, + { + "name": "get_status_result_v0", "fields": [ + { "name": "head", "type": "block_position" }, + { "name": "last_irreversible", "type": "block_position" }, + { "name": "trace_begin_block", "type": "uint32" }, + { "name": "trace_end_block", "type": "uint32" }, + { "name": "chain_state_begin_block", "type": "uint32" }, + { "name": "chain_state_end_block", "type": "uint32" } + ] + }, + { + "name": "get_blocks_request_v0", "fields": [ + { "name": "start_block_num", "type": "uint32" }, + { "name": "end_block_num", "type": "uint32" }, + { "name": "max_messages_in_flight", "type": "uint32" }, + { "name": "have_positions", "type": "block_position[]" }, + { "name": "irreversible_only", "type": "bool" }, + { "name": "fetch_block", "type": "bool" }, + { "name": "fetch_traces", "type": "bool" }, + { "name": "fetch_deltas", "type": "bool" } + ] + }, + { + "name": "get_blocks_ack_request_v0", "fields": [ + { "name": "num_messages", "type": "uint32" } + ] + }, + { + "name": "get_blocks_result_v0", "fields": [ + { "name": "head", "type": "block_position" }, + { "name": "last_irreversible", "type": "block_position" }, + { "name": "this_block", "type": "block_position?" }, + { "name": "prev_block", "type": "block_position?" }, + { "name": "block", "type": "bytes?" }, + { "name": "traces", "type": "bytes?" }, + { "name": "deltas", "type": "bytes?" } + ] + }, + { + "name": "row", "fields": [ + { "name": "present", "type": "bool" }, + { "name": "data", "type": "bytes" } + ] + }, + { + "name": "table_delta_v0", "fields": [ + { "name": "name", "type": "string" }, + { "name": "rows", "type": "row[]" } + ] + }, + { + "name": "action", "fields": [ + { "name": "account", "type": "name" }, + { "name": "name", "type": "name" }, + { "name": "authorization", "type": "permission_level[]" }, + { "name": "data", "type": "bytes" } + ] + }, + { + "name": "account_auth_sequence", "fields": [ + { "name": "account", "type": "name" }, + { "name": "sequence", "type": "uint64" } + ] + }, + { + "name": "action_receipt_v0", "fields": [ + { "name": "receiver", "type": "name" }, + { "name": "act_digest", "type": "checksum256" }, + { "name": "global_sequence", "type": "uint64" }, + { "name": "recv_sequence", "type": "uint64" }, + { "name": "auth_sequence", "type": "account_auth_sequence[]" }, + { "name": "code_sequence", "type": "varuint32" }, + { "name": "abi_sequence", "type": "varuint32" } + ] + }, + { + "name": "account_delta", "fields": [ + { "name": "account", "type": "name" }, + { "name": "delta", "type": "int64" } + ] + }, + { + "name": "action_trace_v0", "fields": [ + { "name": "receipt", "type": "action_receipt" }, + { "name": "act", "type": "action" }, + { "name": "context_free", "type": "bool" }, + { "name": "elapsed", "type": "int64" }, + { "name": "console", "type": "string" }, + { "name": "account_ram_deltas", "type": "account_delta[]" }, + { "name": "except", "type": "string?" }, + { "name": "inline_traces", "type": "action_trace[]" } + ] + }, + { + "name": "transaction_trace_v0", "fields": [ + { "name": "id", "type": "checksum256" }, + { "name": "status", "type": "uint8" }, + { "name": "cpu_usage_us", "type": "uint32" }, + { "name": "net_usage_words", "type": "varuint32" }, + { "name": "elapsed", "type": "int64" }, + { "name": "net_usage", "type": "uint64" }, + { "name": "scheduled", "type": "bool" }, + { "name": "action_traces", "type": "action_trace[]" }, + { "name": "except", "type": "string?" }, + { "name": "failed_dtrx_trace", "type": "transaction_trace?" } + ] + }, + { + "name": "packed_transaction", "fields": [ + { "name": "signatures", "type": "signature[]" }, + { "name": "compression", "type": "uint8" }, + { "name": "packed_context_free_data", "type": "bytes" }, + { "name": "packed_trx", "type": "bytes" } + ] + }, + { + "name": "transaction_receipt_header", "fields": [ + { "name": "status", "type": "uint8" }, + { "name": "cpu_usage_us", "type": "uint32" }, + { "name": "net_usage_words", "type": "varuint32" } + ] + }, + { + "name": "transaction_receipt", "base": "transaction_receipt_header", "fields": [ + { "name": "trx", "type": "transaction_variant" } + ] + }, + { + "name": "extension", "fields": [ + { "name": "type", "type": "uint16" }, + { "name": "data", "type": "bytes" } + ] + }, + { + "name": "block_header", "fields": [ + { "name": "timestamp", "type": "block_timestamp_type" }, + { "name": "producer", "type": "name" }, + { "name": "confirmed", "type": "uint16" }, + { "name": "previous", "type": "checksum256" }, + { "name": "transaction_mroot", "type": "checksum256" }, + { "name": "action_mroot", "type": "checksum256" }, + { "name": "schedule_version", "type": "uint32" }, + { "name": "new_producers", "type": "producer_schedule?" }, + { "name": "header_extensions", "type": "extension[]" } + ] + }, + { + "name": "signed_block_header", "base": "block_header", "fields": [ + { "name": "producer_signature", "type": "signature" } + ] + }, + { + "name": "signed_block", "base": "signed_block_header", "fields": [ + { "name": "transactions", "type": "transaction_receipt[]" }, + { "name": "block_extensions", "type": "extension[]" } + ] + }, + { "name": "transaction_header", "fields": [ + { "name": "expiration", "type": "time_point_sec" }, + { "name": "ref_block_num", "type": "uint16" }, + { "name": "ref_block_prefix", "type": "uint32" }, + { "name": "max_net_usage_words", "type": "varuint32" }, + { "name": "max_cpu_usage_ms", "type": "uint8" }, + { "name": "delay_sec", "type": "varuint32" } + ] + }, + { "name": "transaction", "base": "transaction_header", "fields": [ + { "name": "context_free_actions", "type": "action[]" }, + { "name": "actions", "type": "action[]" }, + { "name": "transaction_extensions", "type": "extension[]" } + ] + }, + { + "name": "account_v0", "fields": [ + { "type": "name", "name": "name" }, + { "type": "uint8", "name": "vm_type" }, + { "type": "uint8", "name": "vm_version" }, + { "type": "bool", "name": "privileged" }, + { "type": "time_point", "name": "last_code_update" }, + { "type": "checksum256", "name": "code_version" }, + { "type": "block_timestamp_type", "name": "creation_date" }, + { "type": "bytes", "name": "code" }, + { "type": "bytes", "name": "abi" } + ] + }, + { + "name": "contract_table_v0", "fields": [ + { "type": "name", "name": "code" }, + { "type": "name", "name": "scope" }, + { "type": "name", "name": "table" }, + { "type": "name", "name": "payer" } + ] + }, + { + "name": "contract_row_v0", "fields": [ + { "type": "name", "name": "code" }, + { "type": "name", "name": "scope" }, + { "type": "name", "name": "table" }, + { "type": "uint64", "name": "primary_key" }, + { "type": "name", "name": "payer" }, + { "type": "bytes", "name": "value" } + ] + }, + { + "name": "contract_index64_v0", "fields": [ + { "type": "name", "name": "code" }, + { "type": "name", "name": "scope" }, + { "type": "name", "name": "table" }, + { "type": "uint64", "name": "primary_key" }, + { "type": "name", "name": "payer" }, + { "type": "uint64", "name": "secondary_key" } + ] + }, + { + "name": "contract_index128_v0", "fields": [ + { "type": "name", "name": "code" }, + { "type": "name", "name": "scope" }, + { "type": "name", "name": "table" }, + { "type": "uint64", "name": "primary_key" }, + { "type": "name", "name": "payer" }, + { "type": "uint128", "name": "secondary_key" } + ] + }, + { + "name": "contract_index256_v0", "fields": [ + { "type": "name", "name": "code" }, + { "type": "name", "name": "scope" }, + { "type": "name", "name": "table" }, + { "type": "uint64", "name": "primary_key" }, + { "type": "name", "name": "payer" }, + { "type": "checksum256", "name": "secondary_key" } + ] + }, + { + "name": "contract_index_double_v0", "fields": [ + { "type": "name", "name": "code" }, + { "type": "name", "name": "scope" }, + { "type": "name", "name": "table" }, + { "type": "uint64", "name": "primary_key" }, + { "type": "name", "name": "payer" }, + { "type": "float64", "name": "secondary_key" } + ] + }, + { + "name": "contract_index_long_double_v0", "fields": [ + { "type": "name", "name": "code" }, + { "type": "name", "name": "scope" }, + { "type": "name", "name": "table" }, + { "type": "uint64", "name": "primary_key" }, + { "type": "name", "name": "payer" }, + { "type": "float128", "name": "secondary_key" } + ] + }, + { + "name": "producer_key", "fields": [ + { "type": "name", "name": "producer_name" }, + { "type": "public_key", "name": "block_signing_key" } + ] + }, + { + "name": "producer_schedule", "fields": [ + { "type": "uint32", "name": "version" }, + { "type": "producer_key[]", "name": "producers" } + ] + }, + { + "name": "chain_config_v0", "fields": [ + { "type": "uint64", "name": "max_block_net_usage" }, + { "type": "uint32", "name": "target_block_net_usage_pct" }, + { "type": "uint32", "name": "max_transaction_net_usage" }, + { "type": "uint32", "name": "base_per_transaction_net_usage" }, + { "type": "uint32", "name": "net_usage_leeway" }, + { "type": "uint32", "name": "context_free_discount_net_usage_num" }, + { "type": "uint32", "name": "context_free_discount_net_usage_den" }, + { "type": "uint32", "name": "max_block_cpu_usage" }, + { "type": "uint32", "name": "target_block_cpu_usage_pct" }, + { "type": "uint32", "name": "max_transaction_cpu_usage" }, + { "type": "uint32", "name": "min_transaction_cpu_usage" }, + { "type": "uint32", "name": "max_transaction_lifetime" }, + { "type": "uint32", "name": "deferred_trx_expiration_window" }, + { "type": "uint32", "name": "max_transaction_delay" }, + { "type": "uint32", "name": "max_inline_action_size" }, + { "type": "uint16", "name": "max_inline_action_depth" }, + { "type": "uint16", "name": "max_authority_depth" } + ] + }, + { + "name": "global_property_v0", "fields": [ + { "type": "uint32?", "name": "proposed_schedule_block_num" }, + { "type": "producer_schedule", "name": "proposed_schedule" }, + { "type": "chain_config", "name": "configuration" } + ] + }, + { + "name": "generated_transaction_v0", "fields": [ + { "type": "name", "name": "sender" }, + { "type": "uint128", "name": "sender_id" }, + { "type": "name", "name": "payer" }, + { "type": "checksum256", "name": "trx_id" }, + { "type": "bytes", "name": "packed_trx" } + ] + }, + { + "name": "key_weight", "fields": [ + { "type": "public_key", "name": "key" }, + { "type": "uint16", "name": "weight" } + ] + }, + { + "name": "permission_level", "fields": [ + { "type": "name", "name": "actor" }, + { "type": "name", "name": "permission" } + ] + }, + { + "name": "permission_level_weight", "fields": [ + { "type": "permission_level", "name": "permission" }, + { "type": "uint16", "name": "weight" } + ] + }, + { + "name": "wait_weight", "fields": [ + { "type": "uint32", "name": "wait_sec" }, + { "type": "uint16", "name": "weight" } + ] + }, + { + "name": "authority", "fields": [ + { "type": "uint32", "name": "threshold" }, + { "type": "key_weight[]", "name": "keys" }, + { "type": "permission_level_weight[]", "name": "accounts" }, + { "type": "wait_weight[]", "name": "waits" } + ] + }, + { + "name": "permission_v0", "fields": [ + { "type": "name", "name": "owner" }, + { "type": "name", "name": "name" }, + { "type": "name", "name": "parent" }, + { "type": "time_point", "name": "last_updated" }, + { "type": "authority", "name": "auth" } + ] + }, + { + "name": "permission_link_v0", "fields": [ + { "type": "name", "name": "account" }, + { "type": "name", "name": "code" }, + { "type": "name", "name": "message_type" }, + { "type": "name", "name": "required_permission" } + ] + }, + { + "name": "resource_limits_v0", "fields": [ + { "type": "name", "name": "owner" }, + { "type": "int64", "name": "net_weight" }, + { "type": "int64", "name": "cpu_weight" }, + { "type": "int64", "name": "ram_bytes" } + ] + }, + { + "name": "usage_accumulator_v0", "fields": [ + { "type": "uint32", "name": "last_ordinal" }, + { "type": "uint64", "name": "value_ex" }, + { "type": "uint64", "name": "consumed" } + ] + }, + { + "name": "resource_usage_v0", "fields": [ + { "type": "name", "name": "owner" }, + { "type": "usage_accumulator", "name": "net_usage" }, + { "type": "usage_accumulator", "name": "cpu_usage" }, + { "type": "uint64", "name": "ram_usage" } + ] + }, + { + "name": "resource_limits_state_v0", "fields": [ + { "type": "usage_accumulator", "name": "average_block_net_usage" }, + { "type": "usage_accumulator", "name": "average_block_cpu_usage" }, + { "type": "uint64", "name": "total_net_weight" }, + { "type": "uint64", "name": "total_cpu_weight" }, + { "type": "uint64", "name": "total_ram_bytes" }, + { "type": "uint64", "name": "virtual_net_limit" }, + { "type": "uint64", "name": "virtual_cpu_limit" } + ] + }, + { + "name": "resource_limits_ratio_v0", "fields": [ + { "type": "uint64", "name": "numerator" }, + { "type": "uint64", "name": "denominator" } + ] + }, + { + "name": "elastic_limit_parameters_v0", "fields": [ + { "type": "uint64", "name": "target" }, + { "type": "uint64", "name": "max" }, + { "type": "uint32", "name": "periods" }, + { "type": "uint32", "name": "max_multiplier" }, + { "type": "resource_limits_ratio", "name": "contract_rate" }, + { "type": "resource_limits_ratio", "name": "expand_rate" } + ] + }, + { + "name": "resource_limits_config_v0", "fields": [ + { "type": "elastic_limit_parameters", "name": "cpu_limit_parameters" }, + { "type": "elastic_limit_parameters", "name": "net_limit_parameters" }, + { "type": "uint32", "name": "account_cpu_usage_average_window" }, + { "type": "uint32", "name": "account_net_usage_average_window" } + ] + } + ], + "types": [ + { "new_type_name": "transaction_id", "type": "checksum256" } + ], + "variants": [ + { "name": "request", "types": ["get_status_request_v0", "get_blocks_request_v0", "get_blocks_ack_request_v0"] }, + { "name": "result", "types": ["get_status_result_v0", "get_blocks_result_v0"] }, + + { "name": "action_receipt", "types": ["action_receipt_v0"] }, + { "name": "action_trace", "types": ["action_trace_v0"] }, + { "name": "transaction_trace", "types": ["transaction_trace_v0"] }, + { "name": "transaction_variant", "types": ["transaction_id", "packed_transaction"] }, + + { "name": "table_delta", "types": ["table_delta_v0"] }, + { "name": "account", "types": ["account_v0"] }, + { "name": "contract_table", "types": ["contract_table_v0"] }, + { "name": "contract_row", "types": ["contract_row_v0"] }, + { "name": "contract_index64", "types": ["contract_index64_v0"] }, + { "name": "contract_index128", "types": ["contract_index128_v0"] }, + { "name": "contract_index256", "types": ["contract_index256_v0"] }, + { "name": "contract_index_double", "types": ["contract_index_double_v0"] }, + { "name": "contract_index_long_double", "types": ["contract_index_long_double_v0"] }, + { "name": "chain_config", "types": ["chain_config_v0"] }, + { "name": "global_property", "types": ["global_property_v0"] }, + { "name": "generated_transaction", "types": ["generated_transaction_v0"] }, + { "name": "permission", "types": ["permission_v0"] }, + { "name": "permission_link", "types": ["permission_link_v0"] }, + { "name": "resource_limits", "types": ["resource_limits_v0"] }, + { "name": "usage_accumulator", "types": ["usage_accumulator_v0"] }, + { "name": "resource_usage", "types": ["resource_usage_v0"] }, + { "name": "resource_limits_state", "types": ["resource_limits_state_v0"] }, + { "name": "resource_limits_ratio", "types": ["resource_limits_ratio_v0"] }, + { "name": "elastic_limit_parameters", "types": ["elastic_limit_parameters_v0"] }, + { "name": "resource_limits_config", "types": ["resource_limits_config_v0"] } + ], + "tables": [ + { "name": "account", "type": "account", "key_names": ["name"] }, + { "name": "contract_table", "type": "contract_table", "key_names": ["code", "scope", "table"] }, + { "name": "contract_row", "type": "contract_row", "key_names": ["code", "scope", "table", "primary_key"] }, + { "name": "contract_index64", "type": "contract_index64", "key_names": ["code", "scope", "table", "primary_key"] }, + { "name": "contract_index128", "type": "contract_index128", "key_names": ["code", "scope", "table", "primary_key"] }, + { "name": "contract_index256", "type": "contract_index256", "key_names": ["code", "scope", "table", "primary_key"] }, + { "name": "contract_index_double", "type": "contract_index_double", "key_names": ["code", "scope", "table", "primary_key"] }, + { "name": "contract_index_long_double", "type": "contract_index_long_double", "key_names": ["code", "scope", "table", "primary_key"] }, + { "name": "global_property", "type": "global_property", "key_names": [] }, + { "name": "generated_transaction", "type": "generated_transaction", "key_names": ["sender", "sender_id"] }, + { "name": "permission", "type": "permission", "key_names": ["owner", "name"] }, + { "name": "permission_link", "type": "permission_link", "key_names": ["account", "code", "message_type"] }, + { "name": "resource_limits", "type": "resource_limits", "key_names": ["owner"] }, + { "name": "resource_usage", "type": "resource_usage", "key_names": ["owner"] }, + { "name": "resource_limits_state", "type": "resource_limits_state", "key_names": [] }, + { "name": "resource_limits_config", "type": "resource_limits_config", "key_names": [] } + ] +})"; diff --git a/plugins/test_control_plugin/CMakeLists.txt b/plugins/test_control_plugin/CMakeLists.txt index aa6b1cff397fb608b0b7b3d149476c63018ce876..7e2a79d6c5c3a75dd2668a545fd2611975b4392f 100644 --- a/plugins/test_control_plugin/CMakeLists.txt +++ b/plugins/test_control_plugin/CMakeLists.txt @@ -4,6 +4,6 @@ add_library( test_control_plugin test_control_plugin.cpp ${HEADERS} ) -target_link_libraries( test_control_plugin producer_plugin chain_plugin http_client_plugin appbase eosio_chain eos_utilities ) +target_link_libraries( test_control_plugin producer_plugin chain_plugin http_client_plugin appbase eosio_chain ) target_include_directories( test_control_plugin PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" ) diff --git a/plugins/txn_test_gen_plugin/txn_test_gen_plugin.cpp b/plugins/txn_test_gen_plugin/txn_test_gen_plugin.cpp index 6288e8c347debca3bd529a14b8698786f60908db..6b4753e9919cdfd3fed5e1301b0f081af06f446a 100644 --- a/plugins/txn_test_gen_plugin/txn_test_gen_plugin.cpp +++ b/plugins/txn_test_gen_plugin/txn_test_gen_plugin.cpp @@ -5,7 +5,6 @@ #include #include #include -#include #include #include diff --git a/plugins/wallet_plugin/se_wallet.cpp b/plugins/wallet_plugin/se_wallet.cpp index 6e1a4fe0e1799528727d54ac3296a4fb6df0d8e1..b292495c5cc2a4f50a4a7c28f18c641fdfb9311e 100644 --- a/plugins/wallet_plugin/se_wallet.cpp +++ b/plugins/wallet_plugin/se_wallet.cpp @@ -305,6 +305,14 @@ se_wallet::se_wallet() : my(new detail::se_wallet_impl()) { return; } } + if(sscanf(model, "Macmini%u", &major) == 1 && major >= 8) { + my->populate_existing_keys(); + return; + } + if(sscanf(model, "MacBookAir%u", &major) == 1 && major >= 8) { + my->populate_existing_keys(); + return; + } } EOS_THROW(secure_enclave_exception, "Secure Enclave not supported on this hardware"); diff --git a/programs/CMakeLists.txt b/programs/CMakeLists.txt index b3a656c3b1063677b39256c59a6fc37d9e971dfc..a40ef3b423cabe2447fe5027a8c59de7c9717a87 100644 --- a/programs/CMakeLists.txt +++ b/programs/CMakeLists.txt @@ -2,5 +2,4 @@ add_subdirectory( nodeos ) add_subdirectory( cleos ) add_subdirectory( keosd ) add_subdirectory( eosio-launcher ) -add_subdirectory( eosio-abigen ) add_subdirectory( eosio-blocklog ) diff --git a/programs/cleos/eosc.pot b/programs/cleos/eosc.pot index 8196aad741da0ba30038d676075c282edd1bea3b..d092703780909a0fa353c5253ae90cf9c5c6259f 100644 --- a/programs/cleos/eosc.pot +++ b/programs/cleos/eosc.pot @@ -343,16 +343,16 @@ msgstr "" msgid "set or update blockchain action state" msgstr "" -msgid "Transfer EOS from account to account" +msgid "Transfer tokens from account to account" msgstr "" -msgid "The account sending EOS" +msgid "The account sending tokens" msgstr "" -msgid "The account receiving EOS" +msgid "The account receiving tokens" msgstr "" -msgid "The amount of EOS to send" +msgid "The amount of tokens to send" msgstr "" msgid "The memo for the transfer" diff --git a/programs/cleos/main.cpp b/programs/cleos/main.cpp index b2a2c326353610f3d16dc8265d833d24d2c92378..cca242ad26f562d907435acf59353ff92b43056c 100644 --- a/programs/cleos/main.cpp +++ b/programs/cleos/main.cpp @@ -35,7 +35,7 @@ Subcommands: create Create various items, on and off the blockchain get Retrieve various items and information from the blockchain set Set or update blockchain state - transfer Transfer EOS from account to account + transfer Transfer tokens from account to account net Interact with local p2p network connections wallet Interact with local wallet sign Sign a transaction @@ -84,7 +84,6 @@ Options: #include #include #include -#include #include #include @@ -129,7 +128,6 @@ Options: using namespace std; using namespace eosio; using namespace eosio::chain; -using namespace eosio::utilities; using namespace eosio::client::help; using namespace eosio::client::http; using namespace eosio::client::localize; @@ -234,6 +232,13 @@ vector get_account_permissions(const vector& pe return accountPermissions; } +vector get_account_permissions(const vector& permissions, const chain::permission_level& default_permission) { + if (permissions.empty()) + return vector{default_permission}; + else + return get_account_permissions(tx_permission); +} + template fc::variant call( const std::string& url, const std::string& path, @@ -509,7 +514,7 @@ void send_transaction( signed_transaction& trx, int32_t extra_kcpu, packed_trans chain::action create_newaccount(const name& creator, const name& newaccount, public_key_type owner, public_key_type active) { return action { - tx_permission.empty() ? vector{{creator,config::active_name}} : get_account_permissions(tx_permission), + get_account_permissions(tx_permission, {creator,config::active_name}), eosio::chain::newaccount{ .creator = creator, .name = newaccount, @@ -528,7 +533,7 @@ chain::action create_buyram(const name& creator, const name& newaccount, const a ("payer", creator.to_string()) ("receiver", newaccount.to_string()) ("quant", quantity.to_string()); - return create_action(tx_permission.empty() ? vector{{creator,config::active_name}} : get_account_permissions(tx_permission), + return create_action(get_account_permissions(tx_permission, {creator,config::active_name}), config::system_account_name, N(buyram), act_payload); } @@ -537,7 +542,7 @@ chain::action create_buyrambytes(const name& creator, const name& newaccount, ui ("payer", creator.to_string()) ("receiver", newaccount.to_string()) ("bytes", numbytes); - return create_action(tx_permission.empty() ? vector{{creator,config::active_name}} : get_account_permissions(tx_permission), + return create_action(get_account_permissions(tx_permission, {creator,config::active_name}), config::system_account_name, N(buyrambytes), act_payload); } @@ -548,7 +553,7 @@ chain::action create_delegate(const name& from, const name& receiver, const asse ("stake_net_quantity", net.to_string()) ("stake_cpu_quantity", cpu.to_string()) ("transfer", transfer); - return create_action(tx_permission.empty() ? vector{{from,config::active_name}} : get_account_permissions(tx_permission), + return create_action(get_account_permissions(tx_permission, {from,config::active_name}), config::system_account_name, N(delegatebw), act_payload); } @@ -567,7 +572,7 @@ chain::action create_open(const string& contract, const name& owner, symbol sym, ("symbol", sym) ("ram_payer", ram_payer); return action { - tx_permission.empty() ? vector{{ram_payer,config::active_name}} : get_account_permissions(tx_permission), + get_account_permissions(tx_permission, {ram_payer,config::active_name}), contract, "open", variant_to_bin( contract, N(open), open_ ) }; } @@ -581,14 +586,14 @@ chain::action create_transfer(const string& contract, const name& sender, const ("memo", memo); return action { - tx_permission.empty() ? vector{{sender,config::active_name}} : get_account_permissions(tx_permission), + get_account_permissions(tx_permission, {sender,config::active_name}), contract, "transfer", variant_to_bin( contract, N(transfer), transfer ) }; } chain::action create_setabi(const name& account, const bytes& abi) { return action { - tx_permission.empty() ? vector{{account,config::active_name}} : get_account_permissions(tx_permission), + get_account_permissions(tx_permission, {account,config::active_name}), setabi{ .account = account, .abi = abi @@ -598,7 +603,7 @@ chain::action create_setabi(const name& account, const bytes& abi) { chain::action create_setcode(const name& account, const bytes& code) { return action { - tx_permission.empty() ? vector{{account,config::active_name}} : get_account_permissions(tx_permission), + get_account_permissions(tx_permission, {account,config::active_name}), setcode{ .account = account, .vmtype = 0, @@ -609,22 +614,22 @@ chain::action create_setcode(const name& account, const bytes& code) { } chain::action create_updateauth(const name& account, const name& permission, const name& parent, const authority& auth) { - return action { tx_permission.empty() ? vector{{account,config::active_name}} : get_account_permissions(tx_permission), + return action { get_account_permissions(tx_permission, {account,config::active_name}), updateauth{account, permission, parent, auth}}; } chain::action create_deleteauth(const name& account, const name& permission) { - return action { tx_permission.empty() ? vector{{account,config::active_name}} : get_account_permissions(tx_permission), + return action { get_account_permissions(tx_permission, {account,config::active_name}), deleteauth{account, permission}}; } chain::action create_linkauth(const name& account, const name& code, const name& type, const name& requirement) { - return action { tx_permission.empty() ? vector{{account,config::active_name}} : get_account_permissions(tx_permission), + return action { get_account_permissions(tx_permission, {account,config::active_name}), linkauth{account, code, type, requirement}}; } chain::action create_unlinkauth(const name& account, const name& code, const name& type) { - return action { tx_permission.empty() ? vector{{account,config::active_name}} : get_account_permissions(tx_permission), + return action { get_account_permissions(tx_permission, {account,config::active_name}), unlinkauth{account, code, type}}; } @@ -683,58 +688,134 @@ inline asset to_asset( const string& s ) { } struct set_account_permission_subcommand { - string accountStr; - string permissionStr; - string authorityJsonOrFile; - string parentStr; + name account; + name permission; + string authority_json_or_file; + name parent; + bool add_code; + bool remove_code; set_account_permission_subcommand(CLI::App* accountCmd) { auto permissions = accountCmd->add_subcommand("permission", localized("set parameters dealing with account permissions")); - permissions->add_option("account", accountStr, localized("The account to set/delete a permission authority for"))->required(); - permissions->add_option("permission", permissionStr, localized("The permission name to set/delete an authority for"))->required(); - permissions->add_option("authority", authorityJsonOrFile, localized("[delete] NULL, [create/update] public key, JSON string, or filename defining the authority"))->required(); - permissions->add_option("parent", parentStr, localized("[create] The permission name of this parents permission (Defaults to: \"Active\")")); + permissions->add_option("account", account, localized("The account to set/delete a permission authority for"))->required(); + permissions->add_option("permission", permission, localized("The permission name to set/delete an authority for"))->required(); + permissions->add_option("authority", authority_json_or_file, localized("[delete] NULL, [create/update] public key, JSON string or filename defining the authority, [code] contract name")); + permissions->add_option("parent", parent, localized("[create] The permission name of this parents permission, defaults to 'active'")); + permissions->add_flag("--add-code", add_code, localized("[code] add '${code}' permission to specified permission authority", ("code", name(config::eosio_code_name)))); + permissions->add_flag("--remove-code", remove_code, localized("[code] remove '${code}' permission from specified permission authority", ("code", name(config::eosio_code_name)))); add_standard_transaction_options(permissions, "account@active"); permissions->set_callback([this] { - name account = name(accountStr); - name permission = name(permissionStr); - bool is_delete = boost::iequals(authorityJsonOrFile, "null"); + EOSC_ASSERT( !(add_code && remove_code), "ERROR: Either --add-code or --remove-code can be set" ); + EOSC_ASSERT( (add_code ^ remove_code) || !authority_json_or_file.empty(), "ERROR: authority should be specified unless add or remove code permission" ); - if (is_delete) { - send_actions({create_deleteauth(account, permission)}); - } else { - authority auth = parse_json_authority_or_key(authorityJsonOrFile); + authority auth; + + bool need_parent = parent.empty() && (permission != name("owner")); + bool need_auth = add_code || remove_code; + + if ( !need_auth && boost::iequals(authority_json_or_file, "null") ) { + send_actions( { create_deleteauth(account, permission) } ); + return; + } - name parent; - if (parentStr.size() == 0 && permissionStr != "owner") { + if ( need_parent || need_auth ) { + fc::variant json = call(get_account_func, fc::mutable_variant_object("account_name", account.to_string())); + auto res = json.as(); + auto itr = std::find_if(res.permissions.begin(), res.permissions.end(), [&](const auto& perm) { + return perm.perm_name == permission; + }); + + if ( need_parent ) { // see if we can auto-determine the proper parent - const auto account_result = call(get_account_func, fc::mutable_variant_object("account_name", accountStr)); - const auto& existing_permissions = account_result.get_object()["permissions"].get_array(); - auto permissionPredicate = [this](const auto& perm) { - return perm.is_object() && - perm.get_object().contains("perm_name") && - boost::equals(perm.get_object()["perm_name"].get_string(), permissionStr); - }; - - auto itr = boost::find_if(existing_permissions, permissionPredicate); - if (itr != existing_permissions.end()) { - parent = name((*itr).get_object()["parent"].get_string()); + if ( itr != res.permissions.end() ) { + parent = (*itr).parent; } else { // if this is a new permission and there is no parent we default to "active" parent = name(config::active_name); + } + } + if ( need_auth ) { + auto actor = (authority_json_or_file.empty()) ? account : name(authority_json_or_file); + auto code_name = name(config::eosio_code_name); + + if ( itr != res.permissions.end() ) { + // fetch existing authority + auth = std::move((*itr).required_auth); + + auto code_perm = permission_level { actor, code_name }; + auto itr2 = std::lower_bound(auth.accounts.begin(), auth.accounts.end(), code_perm, [&](const auto& perm_level, const auto& value) { + return perm_level.permission < value; // Safe since valid authorities must order the permissions in accounts in ascending order + }); + + if ( add_code ) { + if ( itr2 != auth.accounts.end() && itr2->permission == code_perm ) { + // authority already contains code permission, promote its weight to satisfy threshold + if ( (*itr2).weight < auth.threshold ) { + if ( auth.threshold > std::numeric_limits::max() ) { + std::cerr << "ERROR: Threshold is too high to be satisfied by sole code permission" << std::endl; + return; + } + std::cerr << localized("The weight of '${actor}@${code}' in '${permission}' permission authority will be increased up to threshold", + ("actor", actor)("code", code_name)("permission", permission)) << std::endl; + (*itr2).weight = static_cast(auth.threshold); + } else { + std::cerr << localized("ERROR: The permission '${permission}' already contains '${actor}@${code}'", + ("permission", permission)("actor", actor)("code", code_name)) << std::endl; + return ; + } + } else { + // add code permission to specified authority + if ( auth.threshold > std::numeric_limits::max() ) { + std::cerr << "ERROR: Threshold is too high to be satisfied by sole code permission" << std::endl; + return; + } + auth.accounts.insert( itr2, permission_level_weight { + .permission = { actor, code_name }, + .weight = static_cast(auth.threshold) + }); + } + } else { + if ( itr2 != auth.accounts.end() && itr2->permission == code_perm ) { + // remove code permission, if authority becomes empty by the removal of code permission, delete permission + auth.accounts.erase( itr2 ); + if ( auth.keys.empty() && auth.accounts.empty() && auth.waits.empty() ) { + send_actions( { create_deleteauth(account, permission) } ); + return; + } + } else { + // authority doesn't contain code permission + std::cerr << localized("ERROR: '${actor}@${code}' does not exist in '${permission}' permission authority", + ("actor", actor)("code", code_name)("permission", permission)) << std::endl; + return; + } + } + } else { + if ( add_code ) { + // create new permission including code permission + auth.threshold = 1; + auth.accounts.push_back( permission_level_weight { + .permission = { actor, code_name }, + .weight = 1 + }); + } else { + // specified permission doesn't exist, so failed to remove code permission from it + std::cerr << localized("ERROR: The permission '${permission}' does not exist", ("permission", permission)) << std::endl; + return; + } } - } else { - parent = name(parentStr); } + } - send_actions({create_updateauth(account, permission, parent, auth)}); + if ( !need_auth ) { + auth = parse_json_authority_or_key(authority_json_or_file); } + + send_actions( { create_updateauth(account, permission, parent, auth) } ); }); } - }; struct set_action_permission_subcommand { @@ -869,7 +950,7 @@ struct register_producer_subcommand { register_producer->add_option("producer_key", producer_key_str, localized("The producer's public key"))->required(); register_producer->add_option("url", url, localized("url where info about producer can be found"), true); register_producer->add_option("location", loc, localized("relative location for purpose of nearest neighbor scheduling"), true); - add_standard_transaction_options(register_producer); + add_standard_transaction_options(register_producer, "account@active"); register_producer->set_callback([this] { @@ -879,7 +960,8 @@ struct register_producer_subcommand { } EOS_RETHROW_EXCEPTIONS(public_key_type_exception, "Invalid producer public key: ${public_key}", ("public_key", producer_key_str)) auto regprod_var = regproducer_variant(producer_str, producer_key, url, loc ); - send_actions({create_action({permission_level{producer_str,config::active_name}}, config::system_account_name, N(regproducer), regprod_var)}); + auto accountPermissions = get_account_permissions(tx_permission, {producer_str,config::active_name}); + send_actions({create_action(accountPermissions, config::system_account_name, N(regproducer), regprod_var)}); }); } }; @@ -910,20 +992,20 @@ struct create_account_subcommand { if (!simple) { createAccount->add_option("--stake-net", stake_net, - (localized("The amount of EOS delegated for net bandwidth")))->required(); + (localized("The amount of tokens delegated for net bandwidth")))->required(); createAccount->add_option("--stake-cpu", stake_cpu, - (localized("The amount of EOS delegated for CPU bandwidth")))->required(); + (localized("The amount of tokens delegated for CPU bandwidth")))->required(); createAccount->add_option("--buy-ram-kbytes", buy_ram_bytes_in_kbytes, (localized("The amount of RAM bytes to purchase for the new account in kibibytes (KiB)"))); createAccount->add_option("--buy-ram-bytes", buy_ram_bytes, (localized("The amount of RAM bytes to purchase for the new account in bytes"))); createAccount->add_option("--buy-ram", buy_ram_eos, - (localized("The amount of RAM bytes to purchase for the new account in EOS"))); + (localized("The amount of RAM bytes to purchase for the new account in tokens"))); createAccount->add_flag("--transfer", transfer, - (localized("Transfer voting power and right to unstake EOS to receiver"))); + (localized("Transfer voting power and right to unstake tokens to receiver"))); } - add_standard_transaction_options(createAccount); + add_standard_transaction_options(createAccount, "creator@active"); createAccount->set_callback([this] { if( !active_key_str.size() ) @@ -962,13 +1044,14 @@ struct unregister_producer_subcommand { unregister_producer_subcommand(CLI::App* actionRoot) { auto unregister_producer = actionRoot->add_subcommand("unregprod", localized("Unregister an existing producer")); unregister_producer->add_option("account", producer_str, localized("The account to unregister as a producer"))->required(); - add_standard_transaction_options(unregister_producer); + add_standard_transaction_options(unregister_producer, "account@active"); unregister_producer->set_callback([this] { fc::variant act_payload = fc::mutable_variant_object() ("producer", producer_str); - send_actions({create_action({permission_level{producer_str,config::active_name}}, config::system_account_name, N(unregprod), act_payload)}); + auto accountPermissions = get_account_permissions(tx_permission, {producer_str,config::active_name}); + send_actions({create_action(accountPermissions, config::system_account_name, N(unregprod), act_payload)}); }); } }; @@ -981,14 +1064,15 @@ struct vote_producer_proxy_subcommand { auto vote_proxy = actionRoot->add_subcommand("proxy", localized("Vote your stake through a proxy")); vote_proxy->add_option("voter", voter_str, localized("The voting account"))->required(); vote_proxy->add_option("proxy", proxy_str, localized("The proxy account"))->required(); - add_standard_transaction_options(vote_proxy); + add_standard_transaction_options(vote_proxy, "voter@active"); vote_proxy->set_callback([this] { fc::variant act_payload = fc::mutable_variant_object() ("voter", voter_str) ("proxy", proxy_str) ("producers", std::vector{}); - send_actions({create_action({permission_level{voter_str,config::active_name}}, config::system_account_name, N(voteproducer), act_payload)}); + auto accountPermissions = get_account_permissions(tx_permission, {voter_str,config::active_name}); + send_actions({create_action(accountPermissions, config::system_account_name, N(voteproducer), act_payload)}); }); } }; @@ -1001,7 +1085,7 @@ struct vote_producers_subcommand { auto vote_producers = actionRoot->add_subcommand("prods", localized("Vote for one or more producers")); vote_producers->add_option("voter", voter_str, localized("The voting account"))->required(); vote_producers->add_option("producers", producer_names, localized("The account(s) to vote for. All options from this position and following will be treated as the producer list."))->required(); - add_standard_transaction_options(vote_producers); + add_standard_transaction_options(vote_producers, "voter@active"); vote_producers->set_callback([this] { @@ -1011,7 +1095,8 @@ struct vote_producers_subcommand { ("voter", voter_str) ("proxy", "") ("producers", producer_names); - send_actions({create_action({permission_level{voter_str,config::active_name}}, config::system_account_name, N(voteproducer), act_payload)}); + auto accountPermissions = get_account_permissions(tx_permission, {voter_str,config::active_name}); + send_actions({create_action(accountPermissions, config::system_account_name, N(voteproducer), act_payload)}); }); } }; @@ -1024,7 +1109,7 @@ struct approve_producer_subcommand { auto approve_producer = actionRoot->add_subcommand("approve", localized("Add one producer to list of voted producers")); approve_producer->add_option("voter", voter, localized("The voting account"))->required(); approve_producer->add_option("producer", producer_name, localized("The account to vote for"))->required(); - add_standard_transaction_options(approve_producer); + add_standard_transaction_options(approve_producer, "voter@active"); approve_producer->set_callback([this] { auto result = call(get_table_func, fc::mutable_variant_object("json", true) @@ -1033,10 +1118,16 @@ struct approve_producer_subcommand { ("table", "voters") ("table_key", "owner") ("lower_bound", voter.value) + ("upper_bound", voter.value + 1) + // Less than ideal upper_bound usage preserved so cleos can still work with old buggy nodeos versions + // Change to voter.value when cleos no longer needs to support nodeos versions older than 1.5.0 ("limit", 1) ); auto res = result.as(); - if ( res.rows.empty() || res.rows[0]["owner"].as_string() != name(voter).to_string() ) { + // Condition in if statement below can simply be res.rows.empty() when cleos no longer needs to support nodeos versions older than 1.5.0 + // Although since this subcommand will actually change the voter's vote, it is probably better to just keep this check to protect + // against future potential chain_plugin bugs. + if( res.rows.empty() || res.rows[0].get_object()["owner"].as_string() != name(voter).to_string() ) { std::cerr << "Voter info not found for account " << voter << std::endl; return; } @@ -1057,7 +1148,8 @@ struct approve_producer_subcommand { ("voter", voter) ("proxy", "") ("producers", prods); - send_actions({create_action({permission_level{voter,config::active_name}}, config::system_account_name, N(voteproducer), act_payload)}); + auto accountPermissions = get_account_permissions(tx_permission, {voter,config::active_name}); + send_actions({create_action(accountPermissions, config::system_account_name, N(voteproducer), act_payload)}); }); } }; @@ -1070,7 +1162,7 @@ struct unapprove_producer_subcommand { auto approve_producer = actionRoot->add_subcommand("unapprove", localized("Remove one producer from list of voted producers")); approve_producer->add_option("voter", voter, localized("The voting account"))->required(); approve_producer->add_option("producer", producer_name, localized("The account to remove from voted producers"))->required(); - add_standard_transaction_options(approve_producer); + add_standard_transaction_options(approve_producer, "voter@active"); approve_producer->set_callback([this] { auto result = call(get_table_func, fc::mutable_variant_object("json", true) @@ -1079,10 +1171,16 @@ struct unapprove_producer_subcommand { ("table", "voters") ("table_key", "owner") ("lower_bound", voter.value) + ("upper_bound", voter.value + 1) + // Less than ideal upper_bound usage preserved so cleos can still work with old buggy nodeos versions + // Change to voter.value when cleos no longer needs to support nodeos versions older than 1.5.0 ("limit", 1) ); auto res = result.as(); - if ( res.rows.empty() || res.rows[0]["owner"].as_string() != name(voter).to_string() ) { + // Condition in if statement below can simply be res.rows.empty() when cleos no longer needs to support nodeos versions older than 1.5.0 + // Although since this subcommand will actually change the voter's vote, it is probably better to just keep this check to protect + // against future potential chain_plugin bugs. + if( res.rows.empty() || res.rows[0].get_object()["owner"].as_string() != name(voter).to_string() ) { std::cerr << "Voter info not found for account " << voter << std::endl; return; } @@ -1102,7 +1200,8 @@ struct unapprove_producer_subcommand { ("voter", voter) ("proxy", "") ("producers", prods); - send_actions({create_action({permission_level{voter,config::active_name}}, config::system_account_name, N(voteproducer), act_payload)}); + auto accountPermissions = get_account_permissions(tx_permission, {voter,config::active_name}); + send_actions({create_action(accountPermissions, config::system_account_name, N(voteproducer), act_payload)}); }); } }; @@ -1208,12 +1307,12 @@ struct delegate_bandwidth_subcommand { auto delegate_bandwidth = actionRoot->add_subcommand("delegatebw", localized("Delegate bandwidth")); delegate_bandwidth->add_option("from", from_str, localized("The account to delegate bandwidth from"))->required(); delegate_bandwidth->add_option("receiver", receiver_str, localized("The account to receive the delegated bandwidth"))->required(); - delegate_bandwidth->add_option("stake_net_quantity", stake_net_amount, localized("The amount of EOS to stake for network bandwidth"))->required(); - delegate_bandwidth->add_option("stake_cpu_quantity", stake_cpu_amount, localized("The amount of EOS to stake for CPU bandwidth"))->required(); - delegate_bandwidth->add_option("--buyram", buy_ram_amount, localized("The amount of EOS to buyram")); + delegate_bandwidth->add_option("stake_net_quantity", stake_net_amount, localized("The amount of tokens to stake for network bandwidth"))->required(); + delegate_bandwidth->add_option("stake_cpu_quantity", stake_cpu_amount, localized("The amount of tokens to stake for CPU bandwidth"))->required(); + delegate_bandwidth->add_option("--buyram", buy_ram_amount, localized("The amount of tokens to buyram")); delegate_bandwidth->add_option("--buy-ram-bytes", buy_ram_bytes, localized("The amount of RAM to buy in number of bytes")); - delegate_bandwidth->add_flag("--transfer", transfer, localized("Transfer voting power and right to unstake EOS to receiver")); - add_standard_transaction_options(delegate_bandwidth); + delegate_bandwidth->add_flag("--transfer", transfer, localized("Transfer voting power and right to unstake tokens to receiver")); + add_standard_transaction_options(delegate_bandwidth, "from@active"); delegate_bandwidth->set_callback([this] { fc::variant act_payload = fc::mutable_variant_object() @@ -1222,7 +1321,8 @@ struct delegate_bandwidth_subcommand { ("stake_net_quantity", to_asset(stake_net_amount)) ("stake_cpu_quantity", to_asset(stake_cpu_amount)) ("transfer", transfer); - std::vector acts{create_action({permission_level{from_str,config::active_name}}, config::system_account_name, N(delegatebw), act_payload)}; + auto accountPermissions = get_account_permissions(tx_permission, {from_str,config::active_name}); + std::vector acts{create_action(accountPermissions, config::system_account_name, N(delegatebw), act_payload)}; EOSC_ASSERT( !(buy_ram_amount.size()) || !buy_ram_bytes, "ERROR: --buyram and --buy-ram-bytes cannot be set at the same time" ); if (buy_ram_amount.size()) { acts.push_back( create_buyram(from_str, receiver_str, to_asset(buy_ram_amount)) ); @@ -1245,9 +1345,9 @@ struct undelegate_bandwidth_subcommand { auto undelegate_bandwidth = actionRoot->add_subcommand("undelegatebw", localized("Undelegate bandwidth")); undelegate_bandwidth->add_option("from", from_str, localized("The account undelegating bandwidth"))->required(); undelegate_bandwidth->add_option("receiver", receiver_str, localized("The account to undelegate bandwidth from"))->required(); - undelegate_bandwidth->add_option("unstake_net_quantity", unstake_net_amount, localized("The amount of EOS to undelegate for network bandwidth"))->required(); - undelegate_bandwidth->add_option("unstake_cpu_quantity", unstake_cpu_amount, localized("The amount of EOS to undelegate for CPU bandwidth"))->required(); - add_standard_transaction_options(undelegate_bandwidth); + undelegate_bandwidth->add_option("unstake_net_quantity", unstake_net_amount, localized("The amount of tokens to undelegate for network bandwidth"))->required(); + undelegate_bandwidth->add_option("unstake_cpu_quantity", unstake_cpu_amount, localized("The amount of tokens to undelegate for CPU bandwidth"))->required(); + add_standard_transaction_options(undelegate_bandwidth, "from@active"); undelegate_bandwidth->set_callback([this] { fc::variant act_payload = fc::mutable_variant_object() @@ -1255,7 +1355,8 @@ struct undelegate_bandwidth_subcommand { ("receiver", receiver_str) ("unstake_net_quantity", to_asset(unstake_net_amount)) ("unstake_cpu_quantity", to_asset(unstake_cpu_amount)); - send_actions({create_action({permission_level{from_str,config::active_name}}, config::system_account_name, N(undelegatebw), act_payload)}); + auto accountPermissions = get_account_permissions(tx_permission, {from_str,config::active_name}); + send_actions({create_action(accountPermissions, config::system_account_name, N(undelegatebw), act_payload)}); }); } }; @@ -1268,47 +1369,56 @@ struct bidname_subcommand { auto bidname = actionRoot->add_subcommand("bidname", localized("Name bidding")); bidname->add_option("bidder", bidder_str, localized("The bidding account"))->required(); bidname->add_option("newname", newname_str, localized("The bidding name"))->required(); - bidname->add_option("bid", bid_amount, localized("The amount of EOS to bid"))->required(); - add_standard_transaction_options(bidname); + bidname->add_option("bid", bid_amount, localized("The amount of tokens to bid"))->required(); + add_standard_transaction_options(bidname, "bidder@active"); bidname->set_callback([this] { fc::variant act_payload = fc::mutable_variant_object() ("bidder", bidder_str) ("newname", newname_str) ("bid", to_asset(bid_amount)); - send_actions({create_action({permission_level{bidder_str, config::active_name}}, config::system_account_name, N(bidname), act_payload)}); + auto accountPermissions = get_account_permissions(tx_permission, {bidder_str,config::active_name}); + send_actions({create_action(accountPermissions, config::system_account_name, N(bidname), act_payload)}); }); } }; struct bidname_info_subcommand { bool print_json = false; - string newname_str; + name newname; bidname_info_subcommand(CLI::App* actionRoot) { auto list_producers = actionRoot->add_subcommand("bidnameinfo", localized("Get bidname info")); list_producers->add_flag("--json,-j", print_json, localized("Output in JSON format")); - list_producers->add_option("newname", newname_str, localized("The bidding name"))->required(); + list_producers->add_option("newname", newname, localized("The bidding name"))->required(); list_producers->set_callback([this] { auto rawResult = call(get_table_func, fc::mutable_variant_object("json", true) ("code", "eosio")("scope", "eosio")("table", "namebids") - ("lower_bound", eosio::chain::string_to_name(newname_str.c_str()))("limit", 1)); + ("lower_bound", newname.value) + ("upper_bound", newname.value + 1) + // Less than ideal upper_bound usage preserved so cleos can still work with old buggy nodeos versions + // Change to newname.value when cleos no longer needs to support nodeos versions older than 1.5.0 + ("limit", 1)); if ( print_json ) { std::cout << fc::json::to_pretty_string(rawResult) << std::endl; return; } auto result = rawResult.as(); - if ( result.rows.empty() ) { + // Condition in if statement below can simply be res.rows.empty() when cleos no longer needs to support nodeos versions older than 1.5.0 + if( result.rows.empty() || result.rows[0].get_object()["newname"].as_string() != newname.to_string() ) { std::cout << "No bidname record found" << std::endl; return; } - for ( auto& row : result.rows ) { - fc::time_point time(fc::microseconds(row["last_bid_time"].as_uint64())); - int64_t bid = row["high_bid"].as_int64(); - std::cout << std::left << std::setw(18) << "bidname:" << std::right << std::setw(24) << row["newname"].as_string() << "\n" - << std::left << std::setw(18) << "highest bidder:" << std::right << std::setw(24) << row["high_bidder"].as_string() << "\n" - << std::left << std::setw(18) << "highest bid:" << std::right << std::setw(24) << (bid > 0 ? bid : -bid) << "\n" - << std::left << std::setw(18) << "last bid time:" << std::right << std::setw(24) << ((std::string)time).c_str() << std::endl; - if (bid < 0) std::cout << "This auction has already closed" << std::endl; + const auto& row = result.rows[0]; + string time = row["last_bid_time"].as_string(); + try { + time = (string)fc::time_point(fc::microseconds(to_uint64(time))); + } catch (fc::parse_error_exception&) { } + int64_t bid = row["high_bid"].as_int64(); + std::cout << std::left << std::setw(18) << "bidname:" << std::right << std::setw(24) << row["newname"].as_string() << "\n" + << std::left << std::setw(18) << "highest bidder:" << std::right << std::setw(24) << row["high_bidder"].as_string() << "\n" + << std::left << std::setw(18) << "highest bid:" << std::right << std::setw(24) << (bid > 0 ? bid : -bid) << "\n" + << std::left << std::setw(18) << "last bid time:" << std::right << std::setw(24) << time << std::endl; + if (bid < 0) std::cout << "This auction has already closed" << std::endl; }); } }; @@ -1361,10 +1471,10 @@ struct buyram_subcommand { auto buyram = actionRoot->add_subcommand("buyram", localized("Buy RAM")); buyram->add_option("payer", from_str, localized("The account paying for RAM"))->required(); buyram->add_option("receiver", receiver_str, localized("The account receiving bought RAM"))->required(); - buyram->add_option("amount", amount, localized("The amount of EOS to pay for RAM, or number of bytes/kibibytes of RAM if --bytes/--kbytes is set"))->required(); + buyram->add_option("amount", amount, localized("The amount of tokens to pay for RAM, or number of bytes/kibibytes of RAM if --bytes/--kbytes is set"))->required(); buyram->add_flag("--kbytes,-k", kbytes, localized("buyram in number of kibibytes (KiB)")); buyram->add_flag("--bytes,-b", bytes, localized("buyram in number of bytes")); - add_standard_transaction_options(buyram); + add_standard_transaction_options(buyram, "payer@active"); buyram->set_callback([this] { EOSC_ASSERT( !kbytes || !bytes, "ERROR: --kbytes and --bytes cannot be set at the same time" ); if (kbytes || bytes) { @@ -1383,15 +1493,16 @@ struct sellram_subcommand { sellram_subcommand(CLI::App* actionRoot) { auto sellram = actionRoot->add_subcommand("sellram", localized("Sell RAM")); - sellram->add_option("account", receiver_str, localized("The account to receive EOS for sold RAM"))->required(); + sellram->add_option("account", receiver_str, localized("The account to receive tokens for sold RAM"))->required(); sellram->add_option("bytes", amount, localized("Number of RAM bytes to sell"))->required(); - add_standard_transaction_options(sellram); + add_standard_transaction_options(sellram, "account@active"); sellram->set_callback([this] { fc::variant act_payload = fc::mutable_variant_object() ("account", receiver_str) ("bytes", amount); - send_actions({create_action({permission_level{receiver_str,config::active_name}}, config::system_account_name, N(sellram), act_payload)}); + auto accountPermissions = get_account_permissions(tx_permission, {receiver_str,config::active_name}); + send_actions({create_action(accountPermissions, config::system_account_name, N(sellram), act_payload)}); }); } }; @@ -1402,12 +1513,13 @@ struct claimrewards_subcommand { claimrewards_subcommand(CLI::App* actionRoot) { auto claim_rewards = actionRoot->add_subcommand("claimrewards", localized("Claim producer rewards")); claim_rewards->add_option("owner", owner, localized("The account to claim rewards for"))->required(); - add_standard_transaction_options(claim_rewards); + add_standard_transaction_options(claim_rewards, "owner@active"); claim_rewards->set_callback([this] { fc::variant act_payload = fc::mutable_variant_object() ("owner", owner); - send_actions({create_action({permission_level{owner,config::active_name}}, config::system_account_name, N(claimrewards), act_payload)}); + auto accountPermissions = get_account_permissions(tx_permission, {owner,config::active_name}); + send_actions({create_action(accountPermissions, config::system_account_name, N(claimrewards), act_payload)}); }); } }; @@ -1418,13 +1530,14 @@ struct regproxy_subcommand { regproxy_subcommand(CLI::App* actionRoot) { auto register_proxy = actionRoot->add_subcommand("regproxy", localized("Register an account as a proxy (for voting)")); register_proxy->add_option("proxy", proxy, localized("The proxy account to register"))->required(); - add_standard_transaction_options(register_proxy); + add_standard_transaction_options(register_proxy, "proxy@active"); register_proxy->set_callback([this] { fc::variant act_payload = fc::mutable_variant_object() ("proxy", proxy) ("isproxy", true); - send_actions({create_action({permission_level{proxy,config::active_name}}, config::system_account_name, N(regproxy), act_payload)}); + auto accountPermissions = get_account_permissions(tx_permission, {proxy,config::active_name}); + send_actions({create_action(accountPermissions, config::system_account_name, N(regproxy), act_payload)}); }); } }; @@ -1435,13 +1548,14 @@ struct unregproxy_subcommand { unregproxy_subcommand(CLI::App* actionRoot) { auto unregister_proxy = actionRoot->add_subcommand("unregproxy", localized("Unregister an account as a proxy (for voting)")); unregister_proxy->add_option("proxy", proxy, localized("The proxy account to unregister"))->required(); - add_standard_transaction_options(unregister_proxy); + add_standard_transaction_options(unregister_proxy, "proxy@active"); unregister_proxy->set_callback([this] { fc::variant act_payload = fc::mutable_variant_object() ("proxy", proxy) ("isproxy", false); - send_actions({create_action({permission_level{proxy,config::active_name}}, config::system_account_name, N(regproxy), act_payload)}); + auto accountPermissions = get_account_permissions(tx_permission, {proxy,config::active_name}); + send_actions({create_action(accountPermissions, config::system_account_name, N(regproxy), act_payload)}); }); } }; @@ -1456,14 +1570,15 @@ struct canceldelay_subcommand { cancel_delay->add_option("canceling_account", canceling_account, localized("Account from authorization on the original delayed transaction"))->required(); cancel_delay->add_option("canceling_permission", canceling_permission, localized("Permission from authorization on the original delayed transaction"))->required(); cancel_delay->add_option("trx_id", trx_id, localized("The transaction id of the original delayed transaction"))->required(); - add_standard_transaction_options(cancel_delay); + add_standard_transaction_options(cancel_delay, "canceling_account@canceling_permission"); cancel_delay->set_callback([this] { - const auto canceling_auth = permission_level{canceling_account, canceling_permission}; + auto canceling_auth = permission_level{canceling_account, canceling_permission}; fc::variant act_payload = fc::mutable_variant_object() ("canceling_auth", canceling_auth) ("trx_id", trx_id); - send_actions({create_action({canceling_auth}, config::system_account_name, N(canceldelay), act_payload)}); + auto accountPermissions = get_account_permissions(tx_permission, canceling_auth); + send_actions({create_action(accountPermissions, config::system_account_name, N(canceldelay), act_payload)}); }); } }; @@ -2018,6 +2133,8 @@ int main( int argc, char** argv ) { bool binary = false; uint32_t limit = 10; string index_position; + bool reverse = false; + bool show_payer = false; auto getTable = get->add_subcommand( "table", localized("Retrieve the contents of a database table"), false); getTable->add_option( "account", code, localized("The account who owns the table") )->required(); getTable->add_option( "scope", scope, localized("The scope within the contract in which the table is found") )->required(); @@ -2035,7 +2152,9 @@ int main( int argc, char** argv ) { "\t\t\t\tSpecial type 'name' indicates an account name.")); getTable->add_option( "--encode-type", encode_type, localized("The encoding type of key_type (i64 , i128 , float64, float128) only support decimal encoding e.g. 'dec'" - "i256 - supports both 'dec' and 'hex', ripemd160 and sha256 is 'hex' only\n")); + "i256 - supports both 'dec' and 'hex', ripemd160 and sha256 is 'hex' only")); + getTable->add_flag("-r,--reverse", reverse, localized("Iterate in reverse order")); + getTable->add_flag("--show-payer", show_payer, localized("show RAM payer")); getTable->set_callback([&] { @@ -2050,6 +2169,8 @@ int main( int argc, char** argv ) { ("key_type",key_type) ("index_position", index_position) ("encode_type", encode_type) + ("reverse", reverse) + ("show_payer", show_payer) ); std::cout << fc::json::to_pretty_string(result) @@ -2062,12 +2183,14 @@ int main( int argc, char** argv ) { getScope->add_option( "-l,--limit", limit, localized("The maximum number of rows to return") ); getScope->add_option( "-L,--lower", lower, localized("lower bound of scope") ); getScope->add_option( "-U,--upper", upper, localized("upper bound of scope") ); + getScope->add_flag("-r,--reverse", reverse, localized("Iterate in reverse order")); getScope->set_callback([&] { auto result = call(get_table_by_scope_func, fc::mutable_variant_object("code",code) ("table",table) ("lower_bound",lower) ("upper_bound",upper) ("limit",limit) + ("reverse", reverse) ); std::cout << fc::json::to_pretty_string(result) << std::endl; @@ -2353,9 +2476,7 @@ int main( int argc, char** argv ) { bytes code_bytes; if(!contract_clear){ std::string wasm; - fc::path cpath(contractPath); - - if( cpath.filename().generic_string() == "." ) cpath = cpath.parent_path(); + fc::path cpath = fc::canonical(fc::path(contractPath)); if( wasmPath.empty() ) wasmPath = (cpath / (cpath.filename().generic_string()+".wasm")).generic_string(); @@ -2364,7 +2485,7 @@ int main( int argc, char** argv ) { std::cerr << localized(("Reading WASM from " + wasmPath + "...").c_str()) << std::endl; fc::read_file_contents(wasmPath, wasm); - EOS_ASSERT( !wasm.empty(), wast_file_not_found, "no wasm file found ${f}", ("f", wasmPath) ); + EOS_ASSERT( !wasm.empty(), wasm_file_not_found, "no wasm file found ${f}", ("f", wasmPath) ); const string binary_wasm_header("\x00\x61\x73\x6d\x01\x00\x00\x00", 8); if(wasm.compare(0, 8, binary_wasm_header)) @@ -2408,8 +2529,7 @@ int main( int argc, char** argv ) { bytes abi_bytes; if(!contract_clear){ - fc::path cpath(contractPath); - if( cpath.filename().generic_string() == "." ) cpath = cpath.parent_path(); + fc::path cpath = fc::canonical(fc::path(contractPath)); if( abiPath.empty() ) { abiPath = (cpath / (cpath.filename().generic_string()+".abi")).generic_string(); @@ -2478,10 +2598,10 @@ int main( int argc, char** argv ) { string amount; string memo; bool pay_ram = false; - auto transfer = app.add_subcommand("transfer", localized("Transfer EOS from account to account"), false); - transfer->add_option("sender", sender, localized("The account sending EOS"))->required(); - transfer->add_option("recipient", recipient, localized("The account receiving EOS"))->required(); - transfer->add_option("amount", amount, localized("The amount of EOS to send"))->required(); + auto transfer = app.add_subcommand("transfer", localized("Transfer tokens from account to account"), false); + transfer->add_option("sender", sender, localized("The account sending tokens"))->required(); + transfer->add_option("recipient", recipient, localized("The account receiving tokens"))->required(); + transfer->add_option("amount", amount, localized("The amount of tokens to send"))->required(); transfer->add_option("memo", memo, localized("The memo for the transfer")); transfer->add_option("--contract,-c", con, localized("The contract which controls the token")); transfer->add_flag("--pay-ram-to-open", pay_ram, localized("Pay ram to open recipient's token balance row")); @@ -2728,7 +2848,7 @@ int main( int argc, char** argv ) { fc::set_console_echo(true); } - auto priv_key = fc::crypto::private_key::regenerate(*utilities::wif_to_key(str_private_key)); + auto priv_key = private_key_type(str_private_key); trx.sign(priv_key, *chain_id); if(push_trx) { @@ -2829,7 +2949,7 @@ int main( int argc, char** argv ) { }; auto propose_action = msig->add_subcommand("propose", localized("Propose action")); - add_standard_transaction_options(propose_action); + add_standard_transaction_options(propose_action, "proposer@active"); propose_action->add_option("proposal_name", proposal_name, localized("proposal name (string)"))->required(); propose_action->add_option("requested_permissions", requested_perm, localized("The JSON string or filename defining requested permissions"))->required(); propose_action->add_option("trx_permissions", transaction_perm, localized("The JSON string or filename defining transaction permissions"))->required(); @@ -2898,9 +3018,9 @@ int main( int argc, char** argv ) { send_actions({chain::action{accountPermissions, "eosio.msig", "propose", variant_to_bin( N(eosio.msig), N(propose), args ) }}); }); - //multisige propose transaction + //multisig propose transaction auto propose_trx = msig->add_subcommand("propose_trx", localized("Propose transaction")); - add_standard_transaction_options(propose_trx); + add_standard_transaction_options(propose_trx, "proposer@active"); propose_trx->add_option("proposal_name", proposal_name, localized("proposal name (string)"))->required(); propose_trx->add_option("requested_permissions", requested_perm, localized("The JSON string or filename defining requested permissions"))->required(); propose_trx->add_option("transaction", trx_to_push, localized("The JSON string or filename defining the transaction to push"))->required(); @@ -2940,80 +3060,258 @@ int main( int argc, char** argv ) { // multisig review + bool show_approvals_in_multisig_review = false; auto review = msig->add_subcommand("review", localized("Review transaction")); review->add_option("proposer", proposer, localized("proposer name (string)"))->required(); review->add_option("proposal_name", proposal_name, localized("proposal name (string)"))->required(); + review->add_flag( "--show-approvals", show_approvals_in_multisig_review, localized("Show the status of the approvals requested within the proposal") ); review->set_callback([&] { - auto result = call(get_table_func, fc::mutable_variant_object("json", true) - ("code", "eosio.msig") - ("scope", proposer) - ("table", "proposal") - ("table_key", "") - ("lower_bound", eosio::chain::string_to_name(proposal_name.c_str())) - ("upper_bound", "") - ("limit", 1) - ); + const auto result1 = call(get_table_func, fc::mutable_variant_object("json", true) + ("code", "eosio.msig") + ("scope", proposer) + ("table", "proposal") + ("table_key", "") + ("lower_bound", name(proposal_name).value) + ("upper_bound", name(proposal_name).value + 1) + // Less than ideal upper_bound usage preserved so cleos can still work with old buggy nodeos versions + // Change to name(proposal_name).value when cleos no longer needs to support nodeos versions older than 1.5.0 + ("limit", 1) + ); //std::cout << fc::json::to_pretty_string(result) << std::endl; - fc::variants rows = result.get_object()["rows"].get_array(); - if (rows.empty()) { + const auto& rows1 = result1.get_object()["rows"].get_array(); + // Condition in if statement below can simply be rows.empty() when cleos no longer needs to support nodeos versions older than 1.5.0 + if( rows1.empty() || rows1[0].get_object()["proposal_name"] != proposal_name ) { std::cerr << "Proposal not found" << std::endl; return; } - fc::mutable_variant_object obj = rows[0].get_object(); - if (obj["proposal_name"] != proposal_name) { - std::cerr << "Proposal not found" << std::endl; - return; + + const auto& proposal_object = rows1[0].get_object(); + + enum class approval_status { + unapproved, + approved, + invalidated + }; + + std::map> all_approvals; + std::map>> provided_approvers; + + bool new_multisig = true; + if( show_approvals_in_multisig_review ) { + fc::variants rows2; + + try { + const auto& result2 = call(get_table_func, fc::mutable_variant_object("json", true) + ("code", "eosio.msig") + ("scope", proposer) + ("table", "approvals2") + ("table_key", "") + ("lower_bound", name(proposal_name).value) + ("upper_bound", name(proposal_name).value + 1) + // Less than ideal upper_bound usage preserved so cleos can still work with old buggy nodeos versions + // Change to name(proposal_name).value when cleos no longer needs to support nodeos versions older than 1.5.0 + ("limit", 1) + ); + rows2 = result2.get_object()["rows"].get_array(); + } catch( ... ) { + new_multisig = false; + } + + if( !rows2.empty() && rows2[0].get_object()["proposal_name"] == proposal_name ) { + const auto& approvals_object = rows2[0].get_object(); + + for( const auto& ra : approvals_object["requested_approvals"].get_array() ) { + const auto& ra_obj = ra.get_object(); + auto pl = ra["level"].as(); + auto res = all_approvals.emplace( pl, std::make_pair(ra["time"].as(), approval_status::unapproved) ); + } + + for( const auto& pa : approvals_object["provided_approvals"].get_array() ) { + const auto& pa_obj = pa.get_object(); + auto pl = pa["level"].as(); + auto res = all_approvals.emplace( pl, std::make_pair(pa["time"].as(), approval_status::approved) ); + provided_approvers[pl.actor].second.push_back( res.first ); + } + } else { + const auto result3 = call(get_table_func, fc::mutable_variant_object("json", true) + ("code", "eosio.msig") + ("scope", proposer) + ("table", "approvals") + ("table_key", "") + ("lower_bound", name(proposal_name).value) + ("upper_bound", name(proposal_name).value + 1) + // Less than ideal upper_bound usage preserved so cleos can still work with old buggy nodeos versions + // Change to name(proposal_name).value when cleos no longer needs to support nodeos versions older than 1.5.0 + ("limit", 1) + ); + const auto& rows3 = result3.get_object()["rows"].get_array(); + if( rows3.empty() || rows3[0].get_object()["proposal_name"] != proposal_name ) { + std::cerr << "Proposal not found" << std::endl; + return; + } + + const auto& approvals_object = rows3[0].get_object(); + + for( const auto& ra : approvals_object["requested_approvals"].get_array() ) { + auto pl = ra.as(); + auto res = all_approvals.emplace( pl, std::make_pair(fc::time_point{}, approval_status::unapproved) ); + } + + for( const auto& pa : approvals_object["provided_approvals"].get_array() ) { + auto pl = pa.as(); + auto res = all_approvals.emplace( pl, std::make_pair(fc::time_point{}, approval_status::approved) ); + provided_approvers[pl.actor].second.push_back( res.first ); + } + } + + if( new_multisig ) { + for( auto& a : provided_approvers ) { + const auto result4 = call(get_table_func, fc::mutable_variant_object("json", true) + ("code", "eosio.msig") + ("scope", "eosio.msig") + ("table", "invals") + ("table_key", "") + ("lower_bound", a.first.value) + ("upper_bound", a.first.value + 1) + // Less than ideal upper_bound usage preserved so cleos can still work with old buggy nodeos versions + // Change to name(proposal_name).value when cleos no longer needs to support nodeos versions older than 1.5.0 + ("limit", 1) + ); + const auto& rows4 = result4.get_object()["rows"].get_array(); + if( rows4.empty() || rows4[0].get_object()["account"].as() != a.first ) { + continue; + } + + auto invalidation_time = rows4[0].get_object()["last_invalidation_time"].as(); + a.second.first = invalidation_time; + + for( auto& itr : a.second.second ) { + if( invalidation_time >= itr->second.first ) { + itr->second.second = approval_status::invalidated; + } + } + } + } } - auto trx_hex = obj["packed_transaction"].as_string(); + + auto trx_hex = proposal_object["packed_transaction"].as_string(); vector trx_blob(trx_hex.size()/2); fc::from_hex(trx_hex, trx_blob.data(), trx_blob.size()); transaction trx = fc::raw::unpack(trx_blob); + fc::mutable_variant_object obj; + obj["proposer"] = proposer; + obj["proposal_name"] = proposal_object["proposal_name"]; + obj["transaction_id"] = trx.id(); + + for( const auto& entry : proposal_object ) { + if( entry.key() == "proposal_name" ) continue; + obj.set( entry.key(), entry.value() ); + } + fc::variant trx_var; abi_serializer abi; abi.to_variant(trx, trx_var, abi_serializer_resolver, abi_serializer_max_time); obj["transaction"] = trx_var; - std::cout << fc::json::to_pretty_string(obj) - << std::endl; + + if( show_approvals_in_multisig_review ) { + fc::variants approvals; + + for( const auto& approval : all_approvals ) { + fc::mutable_variant_object approval_obj; + approval_obj["level"] = approval.first; + switch( approval.second.second ) { + case approval_status::unapproved: + { + approval_obj["status"] = "unapproved"; + if( approval.second.first != fc::time_point{} ) { + approval_obj["last_unapproval_time"] = approval.second.first; + } + } + break; + case approval_status::approved: + { + approval_obj["status"] = "approved"; + if( new_multisig ) { + approval_obj["last_approval_time"] = approval.second.first; + } + } + break; + case approval_status::invalidated: + { + approval_obj["status"] = "invalidated"; + approval_obj["last_approval_time"] = approval.second.first; + approval_obj["invalidation_time"] = provided_approvers[approval.first.actor].first; + } + break; + } + + approvals.push_back( std::move(approval_obj) ); + } + + obj["approvals"] = std::move(approvals); + } + + std::cout << fc::json::to_pretty_string(obj) << std::endl; }); string perm; + string proposal_hash; auto approve_or_unapprove = [&](const string& action) { fc::variant perm_var; try { perm_var = json_from_file_or_string(perm); } EOS_RETHROW_EXCEPTIONS(transaction_type_exception, "Fail to parse permissions JSON '${data}'", ("data",perm)) + auto args = fc::mutable_variant_object() ("proposer", proposer) ("proposal_name", proposal_name) ("level", perm_var); - auto accountPermissions = tx_permission.empty() ? vector{{sender,config::active_name}} : get_account_permissions(tx_permission); + if( proposal_hash.size() ) { + args("proposal_hash", proposal_hash); + } + + auto accountPermissions = get_account_permissions(tx_permission, {proposer,config::active_name}); send_actions({chain::action{accountPermissions, "eosio.msig", action, variant_to_bin( N(eosio.msig), action, args ) }}); }; // multisig approve auto approve = msig->add_subcommand("approve", localized("Approve proposed transaction")); - add_standard_transaction_options(approve); + add_standard_transaction_options(approve, "proposer@active"); approve->add_option("proposer", proposer, localized("proposer name (string)"))->required(); approve->add_option("proposal_name", proposal_name, localized("proposal name (string)"))->required(); approve->add_option("permissions", perm, localized("The JSON string of filename defining approving permissions"))->required(); + approve->add_option("proposal_hash", proposal_hash, localized("Hash of proposed transaction (i.e. transaction ID) to optionally enforce as a condition of the approval")); approve->set_callback([&] { approve_or_unapprove("approve"); }); // multisig unapprove auto unapprove = msig->add_subcommand("unapprove", localized("Unapprove proposed transaction")); - add_standard_transaction_options(unapprove); + add_standard_transaction_options(unapprove, "proposer@active"); unapprove->add_option("proposer", proposer, localized("proposer name (string)"))->required(); unapprove->add_option("proposal_name", proposal_name, localized("proposal name (string)"))->required(); unapprove->add_option("permissions", perm, localized("The JSON string of filename defining approving permissions"))->required(); unapprove->set_callback([&] { approve_or_unapprove("unapprove"); }); + // multisig invalidate + string invalidator; + auto invalidate = msig->add_subcommand("invalidate", localized("Invalidate all multisig approvals of an account")); + add_standard_transaction_options(invalidate, "invalidator@active"); + invalidate->add_option("invalidator", invalidator, localized("invalidator name (string)"))->required(); + invalidate->set_callback([&] { + auto args = fc::mutable_variant_object() + ("account", invalidator); + + auto accountPermissions = get_account_permissions(tx_permission, {invalidator,config::active_name}); + send_actions({chain::action{accountPermissions, "eosio.msig", "invalidate", variant_to_bin( N(eosio.msig), "invalidate", args ) }}); + }); + // multisig cancel string canceler; auto cancel = msig->add_subcommand("cancel", localized("Cancel proposed transaction")); - add_standard_transaction_options(cancel); + add_standard_transaction_options(cancel, "canceler@active"); cancel->add_option("proposer", proposer, localized("proposer name (string)"))->required(); cancel->add_option("proposal_name", proposal_name, localized("proposal name (string)"))->required(); cancel->add_option("canceler", canceler, localized("canceler name (string)")); @@ -3041,7 +3339,7 @@ int main( int argc, char** argv ) { // multisig exec string executer; auto exec = msig->add_subcommand("exec", localized("Execute proposed transaction")); - add_standard_transaction_options(exec); + add_standard_transaction_options(exec, "executer@active"); exec->add_option("proposer", proposer, localized("proposer name (string)"))->required(); exec->add_option("proposal_name", proposal_name, localized("proposal name (string)"))->required(); exec->add_option("executer", executer, localized("account paying for execution (string)")); @@ -3076,7 +3374,7 @@ int main( int argc, char** argv ) { executer = ""; string trx_to_exec; auto wrap_exec = wrap->add_subcommand("exec", localized("Execute a transaction while bypassing authorization checks")); - add_standard_transaction_options(wrap_exec); + add_standard_transaction_options(wrap_exec, "executer@active & --contract@active"); wrap_exec->add_option("executer", executer, localized("Account executing the transaction and paying for the deferred transaction RAM"))->required(); wrap_exec->add_option("transaction", trx_to_exec, localized("The JSON string or filename defining the transaction to execute"))->required(); wrap_exec->add_option("--contract,-c", wrap_con, localized("The account which controls the wrap contract")); diff --git a/programs/eosio-abigen/CMakeLists.txt b/programs/eosio-abigen/CMakeLists.txt deleted file mode 100644 index 93df3c89ef4d04d8141b23111d2e3d2e5f50d355..0000000000000000000000000000000000000000 --- a/programs/eosio-abigen/CMakeLists.txt +++ /dev/null @@ -1,28 +0,0 @@ -set(SOURCES main.cpp) -find_package(LLVM 4.0 REQUIRED CONFIG) - -link_directories(${LLVM_LIBRARY_DIR}) - -add_executable(eosio-abigen ${SOURCES}) - -set( CMAKE_CXX_STANDARD 14 ) - -if( UNIX AND NOT APPLE ) - set(rt_library rt ) -endif() - -find_package( Gperftools QUIET ) -if( GPERFTOOLS_FOUND ) - message( STATUS "Found gperftools; compiling with TCMalloc") - list( APPEND PLATFORM_SPECIFIC_LIBS tcmalloc ) -endif() - -target_link_libraries(eosio-abigen abi_generator) - - -install( TARGETS - eosio-abigen - RUNTIME DESTINATION ${CMAKE_INSTALL_FULL_BINDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR} - ARCHIVE DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR} -) diff --git a/programs/eosio-abigen/main.cpp b/programs/eosio-abigen/main.cpp deleted file mode 100644 index f15cd138ee4382ae33c0886a8dab9b8385dac276..0000000000000000000000000000000000000000 --- a/programs/eosio-abigen/main.cpp +++ /dev/null @@ -1,106 +0,0 @@ -#include -#include -#include -#include - -using namespace eosio; -using namespace eosio::chain; - -using mvo = fc::mutable_variant_object; - -std::unique_ptr create_factory(bool verbose, bool opt_sfs, string abi_context, abi_def& output, const string& contract, const vector& actions) { - - struct abi_frontend_action_factory : public FrontendActionFactory { - - bool verbose; - bool opt_sfs; - string abi_context; - abi_def& output; - const string& contract; - const vector& actions; - - abi_frontend_action_factory(bool verbose, bool opt_sfs, string abi_context, - abi_def& output, const string& contract, const vector& actions) : verbose(verbose), - abi_context(abi_context), output(output), contract(contract), actions(actions) {} - - clang::FrontendAction *create() override { - return new generate_abi_action(verbose, opt_sfs, abi_context, output, contract, actions); - } - - }; - - return std::unique_ptr( - new abi_frontend_action_factory(verbose, opt_sfs, abi_context, output, contract, actions) - ); -} - -std::unique_ptr create_find_macro_factory(string& contract, vector& actions, string abi_context) { - - struct abi_frontend_macro_action_factory : public FrontendActionFactory { - - string& contract; - vector& actions; - string abi_context; - - abi_frontend_macro_action_factory (string& contract, vector& actions, - string abi_context ) : contract(contract), actions(actions), abi_context(abi_context) {} - - clang::FrontendAction *create() override { - return new find_eosio_abi_macro_action(contract, actions, abi_context); - } - - }; - - return std::unique_ptr( - new abi_frontend_macro_action_factory(contract, actions, abi_context) - ); -} - -static cl::OptionCategory abi_generator_category("ABI generator options"); - -static cl::opt abi_context( - "context", - cl::desc("ABI context"), - cl::cat(abi_generator_category)); - -static cl::opt abi_destination( - "destination-file", - cl::desc("destination json file"), - cl::cat(abi_generator_category)); - -static cl::opt abi_verbose( - "verbose", - cl::desc("show debug info"), - cl::cat(abi_generator_category)); - -static cl::opt abi_opt_sfs( - "optimize-sfs", - cl::desc("Optimize single field struct"), - cl::cat(abi_generator_category)); - -int main(int argc, const char **argv) { abi_def output; try { - CommonOptionsParser op(argc, argv, abi_generator_category); - ClangTool Tool(op.getCompilations(), op.getSourcePathList()); - - string contract; - vector actions; - int result = Tool.run(create_find_macro_factory(contract, actions, abi_context).get()); - if(!result) { - output.version = "eosio::abi/1.0"; - result = Tool.run(create_factory(abi_verbose, abi_opt_sfs, abi_context, output, contract, actions).get()); - if(!result) { - abi_serializer abis(output, fc::seconds(1)); // No risk to client side serialization taking a long time - fc::variant vabi; - to_variant(output, vabi); - - auto comment = fc::format_string( - "This file was generated by eosio-abigen. DO NOT EDIT - ${ts}", - mvo("ts",fc::time_point_sec(fc::time_point::now()).to_iso_string())); - - auto abi_with_comment = mvo("____comment", comment)(mvo(vabi)); - - fc::json::save_to_file(abi_with_comment, abi_destination, true); - } - } - return result; -} FC_CAPTURE_AND_LOG((output)); return -1; } diff --git a/programs/nodeos/CMakeLists.txt b/programs/nodeos/CMakeLists.txt index 9e1481c23c38ff33db0d97da05bcae0ab9e359bf..6bddeacb848045880dc5e2901ce5e4ef85b551ce 100644 --- a/programs/nodeos/CMakeLists.txt +++ b/programs/nodeos/CMakeLists.txt @@ -51,6 +51,7 @@ target_link_libraries( ${NODE_EXECUTABLE_NAME} PRIVATE appbase PRIVATE -Wl,${whole_archive_flag} login_plugin -Wl,${no_whole_archive_flag} PRIVATE -Wl,${whole_archive_flag} history_plugin -Wl,${no_whole_archive_flag} + PRIVATE -Wl,${whole_archive_flag} state_history_plugin -Wl,${no_whole_archive_flag} PRIVATE -Wl,${whole_archive_flag} bnet_plugin -Wl,${no_whole_archive_flag} PRIVATE -Wl,${whole_archive_flag} history_api_plugin -Wl,${no_whole_archive_flag} PRIVATE -Wl,${whole_archive_flag} chain_api_plugin -Wl,${no_whole_archive_flag} diff --git a/programs/nodeos/main.cpp b/programs/nodeos/main.cpp index 9ed46f9cb24f07009c2b96849294f2237bcfbec0..52eb9a0e9ab519761731d4a06c8c7a350669b941 100644 --- a/programs/nodeos/main.cpp +++ b/programs/nodeos/main.cpp @@ -6,10 +6,8 @@ #include #include -#include #include #include -#include #include #include @@ -94,7 +92,6 @@ int main(int argc, char** argv) { try { app().set_version(eosio::nodeos::config::version); - app().register_plugin(); auto root = fc::app_path(); app().set_default_data_dir(root / "eosio/nodeos/data" ); diff --git a/scripts/abi_to_rc/README.md b/scripts/abi_to_rc/README.md deleted file mode 100644 index 70a5439c913ad4fe96f6fa6b60838d431c865769..0000000000000000000000000000000000000000 --- a/scripts/abi_to_rc/README.md +++ /dev/null @@ -1,14 +0,0 @@ -# Purpose -The `abi_to_rc.py` script processes a contract's .abi file in order to generate an overview Ricardian Contract and a Ricardian Contract for each action. The overview Ricardian Contract provides a description of the contract's purpose and also specifies the contract's action(s), input(s), and input type(s). The action Ricardian Contract provides a description of the action's purpose and also specifies the action's input(s), and input type(s). - -## How to run -`$ python abi_to_rc.py /path/to/smart-contract.abi` - -## Example -`$ python abi_to_rc.py ../../contracts/currency/currency.abi` - -## Results -For the example above, `abi_to_rc.py` should generate output files that have the following names: `currency-rc.md`, `currency-transfer-rc.md`, `currency-issue-rc.md`, `currency-create-rc.md`. - -## Notes -Be sure to have `abi_to_rc.py`, `rc-overview-template.md`, and `rc-action-template.md` in the same folder. diff --git a/scripts/abi_to_rc/abi_to_rc.py b/scripts/abi_to_rc/abi_to_rc.py deleted file mode 100644 index 49ccb77bca63082f628652d62db0b6f5a11c5965..0000000000000000000000000000000000000000 --- a/scripts/abi_to_rc/abi_to_rc.py +++ /dev/null @@ -1,135 +0,0 @@ -#!/usr/bin/env python3 - -# By: Jon-Eric Cook -# Github: @joneric - -from string import Template -import argparse -import json -import sys -import os -import re - -# argument parser -parser = argparse.ArgumentParser( - prog="abi_to_rc.py", - description="The abi_to_rc.py script processes a contract's .abi file in order to generate an overview Ricardian Contract and a Ricardian Contract for each action. The overview Ricardian Contract provides a description of the contract's purpose and also specifies the contract's action(s), input(s), and input type(s). The action Ricardian Contract provides a description of the action's purpose and also specifies the action's input(s), and input type(s).", - epilog="example: $ python abi_to_rc.py ../../contracts/currency/currency.abi", - usage="$ python %(prog)s [-h] abi_file") -parser.add_argument("abi_file", help="path to smart contract's .abi file") -args = parser.parse_args() - -# global variables -_RC_OVERVIEW = "rc-overview-template.md" -_RC_ACTION = "rc-action-template.md" -actions = [] -inputs = {} -types = {} - -# checks for abi and template files -def check_for_files(): - if not os.path.isfile(args.abi_file): - abi_filename = os.path.split(args.abi_file)[1] - print("ERROR: %s could not be found" % abi_filename) - exit(1) - if not os.path.isfile(os.path.join(os.path.dirname(sys.argv[0]), _RC_OVERVIEW)): - print("ERROR: %s could not be found" % _RC_OVERVIEW) - exit(1) - if not os.path.isfile(os.path.join(os.path.dirname(sys.argv[0]), _RC_ACTION)): - print("ERROR: %s could not be found" % _RC_ACTION) - exit(1) - -# gets actions, inputs and input types from abi file -def get_actions_inputs_types(): - abi_file = open(args.abi_file,'r') - abi_text = abi_file.read() - abi_file.close() - abi_json = json.loads(abi_text) - actions_json = abi_json['actions'] - for obj in actions_json: - actions.append(obj) - structs_json = abi_json['structs'] - for action in actions: - inputs[action['name']] = [] - types[action['name']] = [] - for struct in structs_json: - for action in actions: - if struct['name'] == action['type']: - for field in struct['fields']: - inputs[action['name']].append(field['name']) - types[action['name']].append(field['type']) - -# builds rows for the table -def build_table_rows(is_action): - table_rows = [] - for action in actions: - action_string = "`{{ " + action['name'] + " }}`" - input_string = "" - input_list = [] - type_string = "" - type_list =[] - if len(inputs[action['name']]) >= 1: - for name in inputs[action['name']]: - input_list.append("`{{ " + name + ("Var }}`" if is_action else " }}`")) - input_string = '
'.join(input_list) - else: - input_string = "`{{ " + action['type'] + ("Var }}`" if is_action else " }}`") - if len(types[action['name']]) >= 1: - for name in types[action['name']]: - type_list.append("`{{ " + name + " }}`") - type_string = '
'.join(type_list) - else: - type_string = "`{{ " + action['type'] + " }}`" - table_rows.append('| ' + action_string + ' | ' + input_string + ' | ' + type_string + ' |') - return table_rows - -# generates an overview ricardian contract from the overview template -def generate_rc_overview_file(): - tr = build_table_rows(False) - abi_file_name = os.path.split(args.abi_file)[1] - contract_name = os.path.splitext(abi_file_name)[0] - rc_file_name = contract_name + '-rc.md' - dirname = os.path.split(args.abi_file)[0] - subs = {'contract': "{{ " + contract_name + " }}", - 'action': 'actions' if len(actions) > 1 else 'action', - 'input': 'inputs' if len(inputs) > 1 else 'input', - 'type': 'types' if len(types) > 1 else 'type'} - subs.update([(k+'_header',v.title()) for k,v in subs.copy().items()]) - rc_file = open(os.path.join(dirname, rc_file_name),"w+") - with open(os.path.join(os.path.dirname(sys.argv[0]), _RC_OVERVIEW)) as fp: - overview_template = Template(fp.read()) - rc_file.write(overview_template.substitute(subs)) - rc_file.write('\n'.join(tr)) - rc_file.close() - -# generates a ricardian contract for each action from the action template -def generate_rc_action_files(): - tr = build_table_rows(True) - abi_filename = os.path.split(args.abi_file)[1] - contract_name = os.path.splitext(abi_filename)[0] - dirname = os.path.split(args.abi_file)[0] - for action in actions: - subs = {'action': "{{ " + action['name'] + " }}", - 'input': 'inputs' if len(inputs[action['name']]) > 1 else 'input', - 'type': 'types' if len(types[action['name']]) > 1 else 'type'} - subs.update([(k+'_header',v.title()) for k,v in subs.copy().items()]) - rc_action_file_name = contract_name + "-" + action['name'] + '-rc.md' - rc_file = open(os.path.join(dirname, rc_action_file_name),"w+") - with open(os.path.join(os.path.dirname(sys.argv[0]), _RC_ACTION)) as fp: - action_template = Template(fp.read()) - rc_file.write(action_template.substitute(subs)) - for row in tr: - if re.search("\\b" + action['name'] + "\\b", row): - rc_file.write(row + "\n") - rc_file.close() - -# main program -def main(): - check_for_files() - get_actions_inputs_types() - generate_rc_overview_file() - generate_rc_action_files() - -# runs main -if __name__== "__main__": - main() \ No newline at end of file diff --git a/scripts/abi_to_rc/rc-action-template.md b/scripts/abi_to_rc/rc-action-template.md deleted file mode 100644 index 04934c92e32e95bfc3cbd52b338f79993b471c86..0000000000000000000000000000000000000000 --- a/scripts/abi_to_rc/rc-action-template.md +++ /dev/null @@ -1,14 +0,0 @@ -# Action - `$action` - -This Contract is legally binding and can be used in the event of a dispute. Disputes shall be settled through the standard arbitration process established by EOS.IO. - -### Description - -The `$action` action... - -### $input_header and Input $type_header - -The `$action` action requires the following `$input` and `input $type`: - -| Action | Input | Input Type | -|:--|:--|:--| diff --git a/scripts/abi_to_rc/rc-overview-template.md b/scripts/abi_to_rc/rc-overview-template.md deleted file mode 100644 index 1f197b1c08e1d7ccc061948505c8d3aa73e8f460..0000000000000000000000000000000000000000 --- a/scripts/abi_to_rc/rc-overview-template.md +++ /dev/null @@ -1,14 +0,0 @@ -# Smart Contract - `$contract` - -This is an overview of the actions for the `$contract` smart contract. This Contract is legally binding and can be used in the event of a dispute. Disputes shall be settled through the standard arbitration process established by EOS.IO. - -### Description - -The `$contract` contract... - -### $action_header, $input_header and Input $type_header - -The table below contains the `$action`, `$input` and `input $type` for the `$contract` contract. - -| Action | Input | Input Type | -|:--|:--|:--| diff --git a/scripts/abigen.sh b/scripts/abigen.sh deleted file mode 100755 index eb5cce98357359dfa175003936ad4fd2874abb72..0000000000000000000000000000000000000000 --- a/scripts/abigen.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash - -if (( $# < 3 )); then - echo "$0 SOURCE_DIR BUILD_DIR ARGS..." - exit 0 -fi - -function get_absolute_dir_path() { - pushd $1 > /dev/null - echo $PWD - popd > /dev/null -} - -SOURCE_DIR=$(get_absolute_dir_path $1) - -BUILD_DIR=$2 - -shift; shift - -#echo "Source directory: ${SOURCE_DIR}" - -eval "${BUILD_DIR}/programs/eosio-abigen/eosio-abigen -extra-arg=--std=c++14 -extra-arg=--target=wasm32 -extra-arg=\"-I${SOURCE_DIR}/contracts/libc++/upstream/include\" -extra-arg=\"-I${SOURCE_DIR}/contracts/musl/upstream/include\" -extra-arg=\"-I${SOURCE_DIR}/externals/magic_get/include\" -extra-arg=\"-I${SOURCE_DIR}/contracts\" $@" diff --git a/scripts/eosio_build_amazon.sh b/scripts/eosio_build_amazon.sh index 6183b0020d558e40185165e9275191538fd82a2e..bac77e2056375f67688852ec4047f57aba55cedb 100644 --- a/scripts/eosio_build_amazon.sh +++ b/scripts/eosio_build_amazon.sh @@ -70,7 +70,7 @@ for (( i=0; i<${#DEP_ARRAY[@]}; i++ )); do - pkg=$( sudo "$YUM" info "${DEP_ARRAY[$i]}" 2>/dev/null | grep Repo | tr -s ' ' | cut -d: -f2 | sed 's/ //g' ) + pkg=$("$YUM" info "${DEP_ARRAY[$i]}" 2>/dev/null | grep Repo | tr -s ' ' | cut -d: -f2 | sed 's/ //g' ) if [ "$pkg" != "installed" ]; then DEP=$DEP" ${DEP_ARRAY[$i]} " diff --git a/scripts/eosio_build_centos.sh b/scripts/eosio_build_centos.sh index 652da373244ef61ba1c9e26f095d0fcaa75129c9..fa5e3c61378968ff2706fe130c326aefb29329f3 100644 --- a/scripts/eosio_build_centos.sh +++ b/scripts/eosio_build_centos.sh @@ -152,7 +152,7 @@ for (( i=0; i<${#DEP_ARRAY[@]}; i++ )); do - pkg=$( sudo "${YUM}" info "${DEP_ARRAY[$i]}" 2>/dev/null | grep Repo | tr -s ' ' | cut -d: -f2 | sed 's/ //g' ) + pkg=$( "${YUM}" info "${DEP_ARRAY[$i]}" 2>/dev/null | grep Repo | tr -s ' ' | cut -d: -f2 | sed 's/ //g' ) if [ "$pkg" != "installed" ]; then DEP=$DEP" ${DEP_ARRAY[$i]} " DISPLAY="${DISPLAY}${COUNT}. ${DEP_ARRAY[$i]}\\n\\t" diff --git a/scripts/eosio_build_fedora.sh b/scripts/eosio_build_fedora.sh index 35cad3d7d8ecd7b5a44e40b2cdb2dbd3041152b0..661efea9fc05cdaef1c2fb825f14d0f8ee8a55c3 100644 --- a/scripts/eosio_build_fedora.sh +++ b/scripts/eosio_build_fedora.sh @@ -69,7 +69,7 @@ for (( i=0; i<${#DEP_ARRAY[@]}; i++ )); do - pkg=$( sudo "${YUM}" info "${DEP_ARRAY[$i]}" 2>/dev/null | grep Repo | tr -s ' ' | cut -d: -f2 | sed 's/ //g' ) + pkg=$( "${YUM}" info "${DEP_ARRAY[$i]}" 2>/dev/null | grep Repo | tr -s ' ' | cut -d: -f2 | sed 's/ //g' ) if [ "$pkg" != "@System" ]; then DEP=$DEP" ${DEP_ARRAY[$i]} " diff --git a/scripts/ricardeos/README.md b/scripts/ricardeos/README.md deleted file mode 100644 index cac5023d95316db33df57e5a92839df707f8fc18..0000000000000000000000000000000000000000 --- a/scripts/ricardeos/README.md +++ /dev/null @@ -1,20 +0,0 @@ -# Purpose -The `ricardeos.py` imports or exports recardian contracts to and from a contracts abi - -## Import Example -`$ python3 ricardeos.py import /path/to/sorce-contract.abi /path/to/new-smart-contract-abi.abi` - -Running this will scan the directory of the abi for all rc.md files and add them to their respective actions. All files with a path format of *clause*-rc.md will be added to the ricardian_clauses section. You can provide the same name for the source and new smart contract abi, the script will prompt you before overwriting. - -The script will also notify the user of any actions that the script cannot find rc.md files for. - -## Export Example -`$ python3 ricardeos.py export /path/to/sorce-contract.abi` - -Running this will dump the contents of all ricardian contracts: - -Actions will be exported in the following format: `--rc.md` - -Clauses will be exported in the following format: `-clause--rc.md` - -If a file already exists the user will be asked if they wish to overwrite the file diff --git a/scripts/ricardeos/ricardeos.py b/scripts/ricardeos/ricardeos.py deleted file mode 100755 index 1110328a529b4f61a49591e3e124d5815ccab44f..0000000000000000000000000000000000000000 --- a/scripts/ricardeos/ricardeos.py +++ /dev/null @@ -1,164 +0,0 @@ -#!/usr/bin/env python3 - -import json -import sys -import os.path -import fnmatch - -def add_ricardian_contracts_to_actions(source_abi_directory, contract_name, abi_actions): - abi_actions_with_ricardian_contracts = [] - - for abi_action in abi_actions: - action_name = abi_action["name"] - contract_action_filename = '{contract_name}-{action_name}-rc.md'.format(contract_name = contract_name, action_name = action_name) - - # check for rc file - rc_contract_path = os.path.join(source_abi_directory, contract_action_filename) - if os.path.exists(rc_contract_path): - print('Importing Contract {contract_action_filename} for {contract_name}:{action_name}'.format( - contract_action_filename = contract_action_filename, - contract_name = contract_name, - action_name = action_name - )) - - with open(rc_contract_path) as contract_file_handle: - contract_contents = contract_file_handle.read() - - abi_action['ricardian_contract'] = contract_contents - else: - print('Did not find recardian contract file {contract_action_filename} for {contract_name}:{action_name}, skipping inclusion'.format( - contract_action_filename = contract_action_filename, - contract_name = contract_name, - action_name = action_name - )) - - abi_actions_with_ricardian_contracts.append(abi_action) - - return abi_actions_with_ricardian_contracts - -def create_ricardian_clauses_list(source_abi_directory, contract_name): - clause_file_pattern = '*-clause*-rc.md' - clause_files = fnmatch.filter(os.listdir(source_abi_directory), clause_file_pattern) - - clause_prefix = 'clause-' - clause_postfix = '-rc.md' - - abi_ricardian_clauses = [] - - for clause_file_name in clause_files: - rc_contract_path = os.path.join(source_abi_directory, clause_file_name) - with open(rc_contract_path) as contract_file_handle: - contract_contents = contract_file_handle.read() - - start_of_clause_id = clause_file_name.index( clause_prefix ) + len( clause_prefix ) - end_of_clause_id = clause_file_name.rindex(clause_postfix, start_of_clause_id) - - clause_id = clause_file_name[start_of_clause_id:end_of_clause_id] - - abi_ricardian_clauses.append({ - 'id': clause_id, - 'body': contract_contents - }) - - return abi_ricardian_clauses - -def add_ricardian_contracts_to_abi(source_abi, output_abi): - source_abi_directory = os.path.dirname(source_abi) - contract_name = os.path.split(source_abi)[1].rpartition(".")[0] - - print('Creating {output_abi} with ricardian contracts included'.format(output_abi = output_abi)) - - with open(source_abi, 'r') as source_abi_file: - source_abi_json = json.load(source_abi_file) - - source_abi_json['actions'] = add_ricardian_contracts_to_actions(source_abi_directory, contract_name, source_abi_json['actions']) - source_abi_json['ricardian_clauses'] = create_ricardian_clauses_list(source_abi_directory, contract_name) - - with open(output_abi, 'w') as output_abi_file: - json.dump(source_abi_json, output_abi_file, indent=2) - -def import_ricardian_to_abi(source_abi, output_abi): - if not os.path.exists(source_abi): - print('Source ABI not found in {source_abi}'.format(source_abi = source_abi)) - sys.exit(0) - - if os.path.exists(output_abi): - overwrite_prompt_response = input('Output ABI {output_abi} already exists, do you want to proceed? (y|n): '.format(output_abi = output_abi)) - if overwrite_prompt_response == 'y': - print('Overwriting existing output abi') - add_ricardian_contracts_to_abi(source_abi, output_abi) - sys.exit(0) - else: - print('User aborted, not overwriting existing abi') - sys.exit(0) - else: - add_ricardian_contracts_to_abi(source_abi, output_abi) - -def write_rc_file(path, filename, content): - output_filename = os.path.join(path, filename) - write_file = True - - if os.path.exists(output_filename): - overwrite_prompt_response = input('Output rc {output_filename} already exists, do you want to proceed? (y|n): '.format(output_filename = output_filename)) - if overwrite_prompt_response == 'y': - print('Overwriting existing output rc') - elif overwrite_prompt_response == 'n': - print('Skipping overwrite of {output_filename}'.format(output_filename = output_filename)) - write_file = False - - if write_file: - with open(output_filename, 'w') as text_file: - print(content, file=text_file) - - print('Wrote {output_filename}'.format(output_filename = output_filename)) - -def export_ricardian_from_abi(source_abi): - source_abi_directory = os.path.dirname(source_abi) - contract_name = os.path.split(source_abi)[1].rpartition(".")[0] - - if not os.path.exists(source_abi): - print('Source ABI not found in {source_abi}'.format(source_abi = source_abi)) - sys.exit(0) - - with open(source_abi, 'r') as source_abi_file: - source_abi_json = json.load(source_abi_file) - - for abi_action in source_abi_json['actions']: - output_action_rc_file_name = '{contract_name}-{action_name}-rc.md'.format(contract_name = contract_name, action_name = abi_action['name']) - write_rc_file(source_abi_directory, output_action_rc_file_name, abi_action['ricardian_contract']) - - for abi_clause in source_abi_json['ricardian_clauses']: - output_clause_rc_file_name = '{contract_name}-clause-{clause_id}-rc.md'.format(contract_name = contract_name, clause_id = abi_clause['id']) - write_rc_file(source_abi_directory, output_clause_rc_file_name, abi_clause['body']) - -def main(): - if len(sys.argv) == 1: - print('Please specify an operation of export or import: ./ricardeos.py ') - sys.exit(1) - - if sys.argv[1] == 'import': - if len(sys.argv) != 4: - print('Please specify a source and destination abi:') - print('Usage: ./ricardeos.py import /eos/contracts/contract/mycontract.abi /eos/contracts/contract/withricardian-mycontract.abi') - - sys.exit(0) - else: - import_ricardian_to_abi(sys.argv[2], sys.argv[3]) - - sys.exit(0) - elif sys.argv[1] == 'export': - if len(sys.argv) != 3: - print('Please specify a source abi:') - print('Usage: ./ricardeos.py export /eos/contracts/contract/mycontract.abi') - - sys.exit(0) - else: - export_ricardian_from_abi(sys.argv[2]) - - sys.exit(0) - - else: - print('Operation not recognized only import and export operations are supported') - -if __name__ == '__main__': - main() diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index ad77d85028577854cd548d048d81032536678b81..c88caa1f99564511bfa00778613cedcf6f53fbeb 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -16,12 +16,11 @@ include_directories("${CMAKE_SOURCE_DIR}/plugins/wallet_plugin/include") file(GLOB UNIT_TESTS "*.cpp") add_executable( plugin_test ${UNIT_TESTS} ${WASM_UNIT_TESTS} ) -target_link_libraries( plugin_test eosio_testing eosio_chain chainbase eos_utilities chain_plugin wallet_plugin abi_generator fc ${PLATFORM_SPECIFIC_LIBS} ) +target_link_libraries( plugin_test eosio_testing eosio_chain chainbase chain_plugin wallet_plugin fc ${PLATFORM_SPECIFIC_LIBS} ) target_include_directories( plugin_test PUBLIC ${CMAKE_SOURCE_DIR}/plugins/net_plugin/include ${CMAKE_SOURCE_DIR}/plugins/chain_plugin/include ) -add_dependencies(plugin_test asserter test_api test_api_mem test_api_db test_api_multi_index proxy identity identity_test stltest infinite eosio.system eosio.token eosio.bios test.inline multi_index_test noop eosio.msig) # configure_file(${CMAKE_CURRENT_SOURCE_DIR}/core_symbol.py.in ${CMAKE_CURRENT_BINARY_DIR}/core_symbol.py) @@ -87,6 +86,8 @@ add_test(NAME nodeos_sanity_bnet_lr_test COMMAND tests/nodeos_run_test.py -v --s set_property(TEST nodeos_sanity_bnet_lr_test PROPERTY LABELS long_running_tests) add_test(NAME nodeos_run_check_lr_test COMMAND tests/nodeos_run_test.py -v --clean-run --dump-error-detail WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) set_property(TEST nodeos_run_check_lr_test PROPERTY LABELS long_running_tests) +add_test(NAME nodeos_remote_lr_test COMMAND tests/nodeos_run_remote_test.py -v --clean-run --dump-error-detail WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) +set_property(TEST nodeos_remote_lr_test PROPERTY LABELS long_running_tests) #add_test(NAME distributed_transactions_lr_test COMMAND tests/distributed-transactions-test.py -d 2 -p 21 -n 21 -v --clean-run --dump-error-detail WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) #set_property(TEST distributed_transactions_lr_test PROPERTY LABELS long_running_tests) diff --git a/tests/Cluster.py b/tests/Cluster.py index 070edd9b3ba1e74b2dbe37a8f57d18a12c336d4b..f26c598033906792305e28e5e9bab96b229816dd 100644 --- a/tests/Cluster.py +++ b/tests/Cluster.py @@ -126,6 +126,9 @@ class Cluster(object): if len(self.nodes) > 0: raise RuntimeError("Cluster already running.") + if pnodes > totalNodes: + raise RuntimeError("totalNodes (%d) must be equal to or greater than pnodes(%d)." % (totalNodes, pnodes)) + if self.walletMgr is None: self.walletMgr=WalletMgr(True) diff --git a/tests/Node.py b/tests/Node.py index 82d6581bb029a965c8c5ced6dc2bca7f9e01e786..5fc4e95dcce8793e4b30082450b64ca112b375e9 100644 --- a/tests/Node.py +++ b/tests/Node.py @@ -259,14 +259,20 @@ class Node(object): cmd="%s %s" % (Utils.MongoPath, self.mongoEndpointArgs) subcommand='db.blocks.findOne( { "block_num": %d } )' % (blockNum) if Utils.Debug: Utils.Print("cmd: echo '%s' | %s" % (subcommand, cmd)) + start=time.perf_counter() try: block=Node.runMongoCmdReturnJson(cmd.split(), subcommand, exitOnError=exitOnError) + if Utils.Debug: + end=time.perf_counter() + Utils.Print("cmd Duration: %.3f sec" % (end-start)) + if block is not None: return block except subprocess.CalledProcessError as ex: if not silentErrors: + end=time.perf_counter() msg=ex.output.decode("utf-8") - errorMsg="Exception during get db node get block. %s" % (msg) + errorMsg="Exception during get db node get block. cmd Duration: %.3f sec. %s" % (end-start, msg) if exitOnError: Utils.cmdError(errorMsg) Utils.errorExit(errorMsg) @@ -280,14 +286,19 @@ class Node(object): cmd="%s %s" % (Utils.MongoPath, self.mongoEndpointArgs) subcommand='db.blocks.findOne( { "block_id": "%s" } )' % (blockId) if Utils.Debug: Utils.Print("cmd: echo '%s' | %s" % (subcommand, cmd)) + start=time.perf_counter() try: trans=Node.runMongoCmdReturnJson(cmd.split(), subcommand) + if Utils.Debug: + end=time.perf_counter() + Utils.Print("cmd Duration: %.3f sec" % (end-start)) if trans is not None: return trans except subprocess.CalledProcessError as ex: if not silentErrors: + end=time.perf_counter() msg=ex.output.decode("utf-8") - Utils.Print("ERROR: Exception during db get block by id. %s" % (msg)) + Utils.Print("ERROR: Exception during db get block by id. cmd Duration: %.3f sec. %s" % (end-start, msg)) return None return None @@ -360,13 +371,18 @@ class Node(object): #subcommand='db.Transactions.findOne( { $and : [ { "trx_id": "%s" }, {"irreversible":true} ] } )' % (transId) subcommand='db.transactions.findOne( { "trx_id": "%s" } )' % (transId) if Utils.Debug: Utils.Print("cmd: echo '%s' | %s" % (subcommand, cmd)) + start=time.perf_counter() try: trans=Node.runMongoCmdReturnJson(cmd.split(), subcommand, exitOnError=exitOnError) + if Utils.Debug: + end=time.perf_counter() + Utils.Print("cmd Duration: %.3f sec" % (end-start)) if trans is not None: return trans except subprocess.CalledProcessError as ex: + end=time.perf_counter() msg=ex.output.decode("utf-8") - errorMsg="Exception during get db node get trans in mongodb with transaction id=%s. %s" % (transId,msg) + errorMsg="Exception during get db node get trans in mongodb with transaction id=%s. cmd Duration: %.3f sec. %s" % (transId, end-start, msg) if exitOnError: Utils.cmdError("" % (errorMsg)) Utils.errorExit("Failed to retrieve transaction in mongodb for transaction id=%s" % (transId)) @@ -548,15 +564,20 @@ class Node(object): try: timeout = 3 for i in range(0,(int(60/timeout) - 1)): + start=time.perf_counter() trans=Node.runMongoCmdReturnJson(cmd.split(), subcommand, exitOnError=exitOnError) if trans is not None: + if Utils.Debug: + end=time.perf_counter() + Utils.Print("cmd Duration: %.3f sec" % (end-start)) return trans time.sleep(timeout) return trans except subprocess.CalledProcessError as ex: msg=ex.output.decode("utf-8") if exitOnError: - Utils.cmdError("Exception during get account from db for %s. %s" % (name, msg)) + end=time.perf_counter() + Utils.cmdError("Exception during get account from db for %s. cmd Duration: %.3f sec. %s" % (name, end-start, msg)) Utils.errorExit("Failed during get account from db for %s. %s" % (name, msg)) Utils.Print("ERROR: Exception during get account from db for %s. %s" % (name, msg)) @@ -675,12 +696,17 @@ class Node(object): s=" ".join(cmdArr) if Utils.Debug: Utils.Print("cmd: %s" % (s)) trans=None + start=time.perf_counter() try: trans=Utils.runCmdArrReturnJson(cmdArr) + if Utils.Debug: + end=time.perf_counter() + Utils.Print("cmd Duration: %.3f sec" % (end-start)) self.trackCmdTransaction(trans) except subprocess.CalledProcessError as ex: + end=time.perf_counter() msg=ex.output.decode("utf-8") - Utils.Print("ERROR: Exception during funds transfer. %s" % (msg)) + Utils.Print("ERROR: Exception during funds transfer. cmd Duration: %.3f sec. %s" % (end-start, msg)) if exitOnError: Utils.cmdError("could not transfer \"%s\" from %s to %s" % (amountStr, source, destination)) Utils.errorExit("Failed to transfer \"%s\" from %s to %s" % (amountStr, source, destination)) @@ -784,13 +810,18 @@ class Node(object): cmd="%s %s" % (Utils.MongoPath, self.mongoEndpointArgs) subcommand='db.action_traces.find({$or: [{"act.data.from":"%s"},{"act.data.to":"%s"}]}).sort({"_id":%d}).limit(%d)' % (account.name, account.name, pos, abs(offset)) if Utils.Debug: Utils.Print("cmd: echo '%s' | %s" % (subcommand, cmd)) + start=time.perf_counter() try: actions=Node.runMongoCmdReturnJson(cmd.split(), subcommand, exitOnError=exitOnError) + if Utils.Debug: + end=time.perf_counter() + Utils.Print("cmd Duration: %.3f sec" % (end-start)) if actions is not None: return actions except subprocess.CalledProcessError as ex: + end=time.perf_counter() msg=ex.output.decode("utf-8") - errorMsg="Exception during get db actions. %s" % (msg) + errorMsg="Exception during get db actions. cmd Duration: %.3f sec. %s" % (end-start, msg) if exitOnError: Utils.cmdError(errorMsg) Utils.errorExit(errorMsg) @@ -834,8 +865,12 @@ class Node(object): def getAccountCodeHash(self, account): cmd="%s %s get code %s" % (Utils.EosClientPath, self.eosClientArgs(), account) if Utils.Debug: Utils.Print("cmd: %s" % (cmd)) + start=time.perf_counter() try: retStr=Utils.checkOutput(cmd.split()) + if Utils.Debug: + end=time.perf_counter() + Utils.Print("cmd Duration: %.3f sec" % (end-start)) #Utils.Print ("get code> %s"% retStr) p=re.compile(r'code\shash: (\w+)\n', re.MULTILINE) m=p.search(retStr) @@ -846,8 +881,9 @@ class Node(object): return m.group(1) except subprocess.CalledProcessError as ex: + end=time.perf_counter() msg=ex.output.decode("utf-8") - Utils.Print("ERROR: Exception during code hash retrieval. %s" % (msg)) + Utils.Print("ERROR: Exception during code hash retrieval. cmd Duration: %.3f sec. %s" % (end-start, msg)) return None # publish contract and return transaction as json object @@ -857,13 +893,18 @@ class Node(object): cmd += "" if abiFile is None else (" " + abiFile) if Utils.Debug: Utils.Print("cmd: %s" % (cmd)) trans=None + start=time.perf_counter() try: trans=Utils.runCmdReturnJson(cmd, trace=False) self.trackCmdTransaction(trans) + if Utils.Debug: + end=time.perf_counter() + Utils.Print("cmd Duration: %.3f sec" % (end-start)) except subprocess.CalledProcessError as ex: if not shouldFail: + end=time.perf_counter() msg=ex.output.decode("utf-8") - Utils.Print("ERROR: Exception during code hash retrieval. %s" % (msg)) + Utils.Print("ERROR: Exception during code hash retrieval. cmd Duration: %.3f sec. %s" % (end-start, msg)) return None else: retMap={} @@ -915,14 +956,19 @@ class Node(object): cmdArr += opts.split() s=" ".join(cmdArr) if Utils.Debug: Utils.Print("cmd: %s" % (cmdArr)) + start=time.perf_counter() try: trans=Utils.runCmdArrReturnJson(cmdArr) self.trackCmdTransaction(trans, ignoreNonTrans=True) + if Utils.Debug: + end=time.perf_counter() + Utils.Print("cmd Duration: %.3f sec" % (end-start)) return (True, trans) except subprocess.CalledProcessError as ex: msg=ex.output.decode("utf-8") if not silentErrors: - Utils.Print("ERROR: Exception during push message. %s" % (msg)) + end=time.perf_counter() + Utils.Print("ERROR: Exception during push message. cmd Duration=%.3f sec. %s" % (end - start, msg)) return (False, msg) def setPermission(self, account, code, pType, requirement, waitForTransBlock=False, exitOnError=False): @@ -976,6 +1022,7 @@ class Node(object): else: exitMsg="" trans=None + start=time.perf_counter() try: if returnType==ReturnType.json: trans=Utils.runCmdReturnJson(cmd, silentErrors=silentErrors) @@ -983,10 +1030,15 @@ class Node(object): trans=Utils.runCmdReturnStr(cmd) else: unhandledEnumType(returnType) + + if Utils.Debug: + end=time.perf_counter() + Utils.Print("cmd Duration: %.3f sec" % (end-start)) except subprocess.CalledProcessError as ex: if not silentErrors: + end=time.perf_counter() msg=ex.output.decode("utf-8") - errorMsg="Exception during \"%s\". Exception message: %s. %s" % (cmdDesc, msg, exitMsg) + errorMsg="Exception during \"%s\". Exception message: %s. cmd Duration=%.3f sec. %s" % (cmdDesc, msg, end-start, exitMsg) if exitOnError: Utils.cmdError(errorMsg) Utils.errorExit(errorMsg) @@ -1010,6 +1062,7 @@ class Node(object): (self.endpointHttp, producer, whereInSequence, basedOnLib) if Utils.Debug: Utils.Print("cmd: %s" % (cmd)) rtn=None + start=time.perf_counter() try: if returnType==ReturnType.json: rtn=Utils.runCmdReturnJson(cmd, silentErrors=silentErrors) @@ -1017,10 +1070,15 @@ class Node(object): rtn=Utils.runCmdReturnStr(cmd) else: unhandledEnumType(returnType) + + if Utils.Debug: + end=time.perf_counter() + Utils.Print("cmd Duration: %.3f sec" % (end-start)) except subprocess.CalledProcessError as ex: if not silentErrors: + end=time.perf_counter() msg=ex.output.decode("utf-8") - errorMsg="Exception during \"%s\". %s" % (cmd, msg) + errorMsg="Exception during \"%s\". %s. cmd Duration=%.3f sec." % (cmd, msg, end-start) if exitOnError: Utils.cmdError(errorMsg) Utils.errorExit(errorMsg) @@ -1065,12 +1123,17 @@ class Node(object): cmd="%s %s" % (Utils.MongoPath, self.mongoEndpointArgs) subcommand="db.blocks.find().sort({\"_id\":%d}).limit(1).pretty()" % (idx) if Utils.Debug: Utils.Print("cmd: echo \"%s\" | %s" % (subcommand, cmd)) + start=time.perf_counter() try: trans=Node.runMongoCmdReturnJson(cmd.split(), subcommand) + if Utils.Debug: + end=time.perf_counter() + Utils.Print("cmd Duration: %.3f sec" % (end-start)) return trans except subprocess.CalledProcessError as ex: + end=time.perf_counter() msg=ex.output.decode("utf-8") - Utils.Print("ERROR: Exception during get db block. %s" % (msg)) + Utils.Print("ERROR: Exception during get db block. cmd Duration: %.3f sec. %s" % (end-start, msg)) return None def checkPulse(self, exitOnError=False): diff --git a/tests/chain_plugin_tests.cpp b/tests/chain_plugin_tests.cpp index 2b7867a07e94b20d0b71dd02911ed8fb91a7bd50..5a489c255b4fd410ca69d9bb860e519f15839c03 100644 --- a/tests/chain_plugin_tests.cpp +++ b/tests/chain_plugin_tests.cpp @@ -12,15 +12,6 @@ #include #include -#include -#include - -#include -#include - -#include -#include - #include #include diff --git a/tests/chain_tests/proof_tests.cpp b/tests/chain_tests/proof_tests.cpp deleted file mode 100644 index 6240443d77d6cca72146478f6d48a8a9a6203844..0000000000000000000000000000000000000000 --- a/tests/chain_tests/proof_tests.cpp +++ /dev/null @@ -1,340 +0,0 @@ -#include -#include -#include -#include - -#ifdef NON_VALIDATING_TEST -#define TESTER tester -#else -#define TESTER validating_tester -#endif - -using namespace eosio; -using namespace eosio::chain; -using namespace eosio::testing; - -struct action_proof_data { - account_name receiver; - scope_name scope; - action_name name; - bytes data; - uint64_t region_id; - uint64_t cycle_index; - vector data_access; -}; -FC_REFLECT(action_proof_data, (receiver)(scope)(name)(data)(region_id)(cycle_index)(data_access)); - - -struct merkle_node { - digest_type digest; - optional left; - optional right; - optional parent; -}; - -digest_type process_merkle(vector& nodes, vector leaf_indices) { - size_t num_nodes = leaf_indices.size(); - size_t base = 0; - - if (num_nodes == 0) { - return digest_type(); - } else if (num_nodes == 1) { - return nodes[leaf_indices.front()].digest; - } - - while (num_nodes > 1) { - size_t new_nodes = (num_nodes / 2) + (num_nodes % 2); - for(size_t idx = 0; idx < new_nodes; idx++) { - size_t l_idx = idx * 2; - size_t r_idx = l_idx + 1; - size_t left = leaf_indices.at(base + l_idx); - if (r_idx >= num_nodes) { - nodes.emplace_back( - merkle_node{ - digest_type::hash(make_canonical_pair(nodes[left].digest, nodes[left].digest)), - left - }); - nodes[left].parent.emplace(nodes.size() - 1); - } else { - size_t right = leaf_indices.at(base + r_idx); - nodes.emplace_back( - merkle_node{ - digest_type::hash(make_canonical_pair(nodes[left].digest, nodes[right].digest)), - left, - right - }); - nodes[left].parent.emplace(nodes.size() - 1); - nodes[right].parent.emplace(nodes.size() - 1); - } - - leaf_indices.emplace_back(nodes.size() - 1); - } - - base += num_nodes; - num_nodes = new_nodes; - } - - return nodes.back().digest; -} - -auto get_proof_path(const vector& nodes, size_t leaf) { - vector path; - digest_type current = nodes[leaf].digest; - while (nodes[leaf].parent.valid()) { - size_t parent = *nodes[leaf].parent; - if (leaf == *nodes[parent].left) { - if (nodes[parent].right.valid()) { - size_t right = *nodes[parent].right; - path.emplace_back(make_canonical_right(nodes[right].digest)); - current = digest_type::hash(make_canonical_pair(nodes[leaf].digest, nodes[right].digest)); - } else { - path.emplace_back(make_canonical_right(nodes[leaf].digest)); - current = digest_type::hash(make_canonical_pair(nodes[leaf].digest, nodes[leaf].digest)); - } - } else { - size_t left = *nodes[parent].left; - path.emplace_back(make_canonical_left(nodes[left].digest)); - current = digest_type::hash(make_canonical_pair(nodes[left].digest, nodes[leaf].digest)); - } - - leaf = parent; - } - - return path; -} - -digest_type apply_path(const digest_type& digest, const vector& path) { - digest_type current = digest; - - for (const auto& p: path ) { - if (is_canonical_left(p)) { - current = digest_type::hash(make_canonical_pair(p, current)); - } else { - current = digest_type::hash(make_canonical_pair(current, p)); - } - } - - return current; -} - -bool proof_is_valid(const digest_type& digest, const vector& path, const digest_type& expected_root) { - return apply_path(digest, path) == expected_root; -} - -BOOST_AUTO_TEST_SUITE(proof_tests) - -BOOST_FIXTURE_TEST_CASE( prove_block_in_chain, validating_tester ) { try { - vector known_blocks; - known_blocks.reserve(100); - block_header last_block_header; - - // register a callback on new blocks to record block information - validating_node->applied_block.connect([&](const block_trace& bt){ - known_blocks.emplace_back(bt.block.id()); - last_block_header = bt.block; - }); - - produce_blocks(100); - return; - vector nodes; - vector ids; - vector block_leaves; - nodes.reserve(100); - ids.reserve(100); - for (const auto& blk_id: known_blocks) { - nodes.emplace_back(merkle_node{blk_id}); - ids.push_back(blk_id); - block_leaves.push_back(nodes.size() - 1); - } - - digest_type block_mroot = process_merkle(nodes, move(block_leaves)); - - BOOST_REQUIRE_EQUAL((std::string)block_mroot, (std::string)merkle(ids)); - - produce_block(); - - BOOST_REQUIRE_EQUAL((std::string)block_mroot, (std::string)last_block_header.block_mroot); - - for (int idx = 0; idx < 100; idx++) { - vector path = get_proof_path(nodes, idx); - - BOOST_REQUIRE_EQUAL(true, proof_is_valid(nodes[idx].digest, path, last_block_header.block_mroot)); - - /** UNCOMMENT TO PRODUCE PROOFS TO STD OUT - std::cout << idx << ":" << std::string(known_blocks.at(idx)) << " = "; - for (const auto& e: path) { - std::cout << std::string(e) << " "; - } - - std::cout << "-> " << std::string(last_block_header.block_mroot) << std::endl; - */ - } - -} FC_LOG_AND_RETHROW() } /// transfer_test - - -struct action_proof_info { - action_trace trace; - - size_t action_leaf; - size_t block_leaf; - - uint32_t cycle_index; - uint32_t region_id; -}; - -/** - * This test case will attempt to allow one account to transfer on behalf - * of another account by updating the active authority. - */ -BOOST_FIXTURE_TEST_CASE( prove_action_in_block, validating_tester ) { try { - vector nodes; - vector block_leaves; - vector known_actions; - map block_action_mroots; - block_header last_block_header; - block_id_type last_block_id; - - // register a callback on new blocks to record block information - validating_node->applied_block.connect([&](const block_trace& bt){ - nodes.emplace_back(merkle_node{bt.block.id()}); - size_t block_leaf = nodes.size() - 1; - block_leaves.push_back(block_leaf); - - vector region_leaves; - - for (uint32_t r_idx = 0; r_idx < bt.region_traces.size(); r_idx++) { - const auto& rt = bt.region_traces.at(r_idx); - - vector shard_leaves; - - for (uint32_t c_idx = 0; c_idx < rt.cycle_traces.size(); c_idx++) { - const auto& ct = rt.cycle_traces.at(c_idx); - - for (const auto& st: ct.shard_traces) { - vector action_leaves; - - for (const auto& tt: st.transaction_traces) { - for (const auto& at: tt.action_traces) { - digest_type::encoder enc; - - auto a_data = action_proof_data { - at.receiver, - at.act.account, - at.act.name, - at.act.data, - tt.region_id, - tt.cycle_index, - at.data_access - }; - fc::raw::pack(enc, a_data); - nodes.emplace_back(merkle_node{enc.result()}); - size_t action_leaf = nodes.size() - 1; - known_actions.emplace_back(action_proof_info{at, action_leaf, block_leaf, c_idx, r_idx }); - action_leaves.emplace_back(action_leaf); - } - } - - if (action_leaves.size() > 0) { - process_merkle(nodes, move(action_leaves)); - } else { - nodes.emplace_back(merkle_node{digest_type()}); - } - shard_leaves.emplace_back(nodes.size() - 1); - } - } - - if (shard_leaves.size() > 0) { - process_merkle(nodes, move(shard_leaves)); - } else { - nodes.emplace_back(merkle_node{digest_type()}); - } - - region_leaves.emplace_back(nodes.size() - 1); - } - - digest_type action_mroot = process_merkle(nodes, move(region_leaves)); - BOOST_REQUIRE_EQUAL((std::string)bt.block.action_mroot, (std::string)action_mroot); - - last_block_header = bt.block; - last_block_id = bt.block.id(); - block_action_mroots[bt.block.id()] = bt.block.action_mroot; - }); - - create_accounts( { N(alice), N(bob), N(carol), N(david), N(elvis) }); - - produce_blocks(50); - - push_dummy(N(alice), "AB"); - push_dummy(N(bob), "BC"); - push_dummy(N(carol), "CD"); - push_dummy(N(david), "DE"); - push_dummy(N(elvis), "EF"); - - produce_blocks(50); - digest_type block_mroot = process_merkle(nodes, move(block_leaves)); - - produce_block(); - BOOST_REQUIRE_EQUAL((std::string)block_mroot, (std::string)last_block_header.block_mroot); - - /* UNCOMMENT TO PRODUCE PROOFS TO STDOUT - std::cout << "Best Block ID: " << (std::string)last_block_id << std::endl; - std::cout << " Merkle Root: " << (std::string)last_block_header.block_mroot << std::endl; - - for(const auto& ai : known_actions) { - auto block_path = get_proof_path(nodes, ai.action_leaf); - auto chain_path = get_proof_path(nodes, ai.block_leaf); - - // prove action in block - auto shard_root = apply_path(nodes[ai.action_leaf].digest, block_path); - BOOST_REQUIRE_EQUAL((std::string)shard_root, (std::string)block_action_mroots[nodes[ai.block_leaf].digest]); - - // prove that block is part of the chain - auto expected_block_mroot = apply_path(nodes[ai.block_leaf].digest, chain_path); - BOOST_REQUIRE_EQUAL((std::string)expected_block_mroot, (std::string)last_block_header.block_mroot); - - std::cout << "Proof for Action:" << std::endl; - std::cout << std::setw(14) << "reciever" << ":" << (std::string) ai.trace.receiver << std::endl; - std::cout << std::setw(14) << "scope" << ":" << (std::string) ai.trace.act.scope << std::endl; - std::cout << std::setw(14) << "name" << ":" << (std::string) ai.trace.act.name << std::endl; - std::cout << std::setw(14) << "data" << ":" << fc::json::to_string(ai.trace.act.as()) << std::endl; - std::cout << std::setw(14) << "data_access" << ":" << fc::json::to_string(ai.trace.data_access) << std::endl; - std::cout << std::setw(14) << "region" << ":" << ai.region_id << std::endl; - std::cout << std::setw(14) << "cycle" << ":" << ai.cycle_index << std::endl; - std::cout << std::setw(14) << "block" << ":" << (std::string)nodes[ai.block_leaf].digest << std::endl; - std::cout << std::setw(14) << "am_root" << ":" << (std::string)block_action_mroots[nodes[ai.block_leaf].digest] << std::endl; - std::cout << std::endl; - - auto a_data = action_proof_data { - ai.trace.receiver, - ai.trace.act.scope, - ai.trace.act.name, - ai.trace.act.data, - ai.trace.region_id, - ai.trace.cycle_index, - ai.trace.data_access - }; - auto action_data = fc::raw::pack(a_data); - - std::cout << "Action Hex: " << fc::to_hex(action_data) << std::endl; - std::cout << "Action Hash: " << (std::string)nodes[ai.action_leaf].digest << std::endl; - - std::cout << "Action Path: "; - for (const auto& p: block_path) { - std::cout << (std::string)p << " "; - } - std::cout << std::endl; - - std::cout << "Block Path: "; - for (const auto& p: chain_path) { - std::cout << (std::string)p << " "; - } - std::cout << std::endl; - }*/ - - -} FC_LOG_AND_RETHROW() } - - - -BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/distributed-transactions-remote-test.py b/tests/distributed-transactions-remote-test.py index 1b678f3be030dcdd822ec91b51c449318de51c72..9e79b352329faf5c740e0bee740e3d2a37ce7ffd 100755 --- a/tests/distributed-transactions-remote-test.py +++ b/tests/distributed-transactions-remote-test.py @@ -58,7 +58,7 @@ try: Print ("producing nodes: %s, non-producing nodes: %d, topology: %s, delay between nodes launch(seconds): %d" % (pnodes, total_nodes-pnodes, topo, delay)) Print("Stand up cluster") - if cluster.launch(pnodes=pnodes, totalNodes=total_nodes, prodCount=prodCount, topo=topo, delay=delay, dontKill=dontKill) is False: + if cluster.launch(pnodes=pnodes, totalNodes=total_nodes, prodCount=prodCount, topo=topo, delay=delay) is False: errorExit("Failed to stand up eos cluster.") Print ("Wait for Cluster stabilization") diff --git a/tests/get_table_tests.cpp b/tests/get_table_tests.cpp index 818ca5562d23beb902b6446dddf9a612a481569b..bb332b9a0007e681e49ee7bea09c0c43e73188f9 100644 --- a/tests/get_table_tests.cpp +++ b/tests/get_table_tests.cpp @@ -12,15 +12,12 @@ #include #include -#include -#include +#include +#include #include #include -#include -#include - #include #include @@ -58,7 +55,7 @@ BOOST_FIXTURE_TEST_CASE( get_scope_test, TESTER ) try { set_abi( N(eosio.token), eosio_token_abi ); produce_blocks(1); - // create currency + // create currency auto act = mutable_variant_object() ("issuer", "eosio") ("maximum_supply", eosio::chain::asset::from_string("1000000000.0000 SYS")); @@ -94,13 +91,13 @@ BOOST_FIXTURE_TEST_CASE( get_scope_test, TESTER ) try { } param.lower_bound = "initb"; - param.upper_bound = "initd"; + param.upper_bound = "initc"; result = plugin.read_only::get_table_by_scope(param); BOOST_REQUIRE_EQUAL(2, result.rows.size()); BOOST_REQUIRE_EQUAL("", result.more); if (result.rows.size() >= 2) { BOOST_REQUIRE_EQUAL(name(N(initb)), result.rows[0].scope); - BOOST_REQUIRE_EQUAL(name(N(initc)), result.rows[1].scope); + BOOST_REQUIRE_EQUAL(name(N(initc)), result.rows[1].scope); } param.limit = 1; @@ -116,9 +113,337 @@ BOOST_FIXTURE_TEST_CASE( get_scope_test, TESTER ) try { param.table = N(invalid); result = plugin.read_only::get_table_by_scope(param); BOOST_REQUIRE_EQUAL(0, result.rows.size()); - BOOST_REQUIRE_EQUAL("", result.more); + BOOST_REQUIRE_EQUAL("", result.more); } FC_LOG_AND_RETHROW() /// get_scope_test -BOOST_AUTO_TEST_SUITE_END() +BOOST_FIXTURE_TEST_CASE( get_table_test, TESTER ) try { + produce_blocks(2); + + create_accounts({ N(eosio.token), N(eosio.ram), N(eosio.ramfee), N(eosio.stake), + N(eosio.bpay), N(eosio.vpay), N(eosio.saving), N(eosio.names) }); + + std::vector accs{N(inita), N(initb)}; + create_accounts(accs); + produce_block(); + + set_code( N(eosio.token), eosio_token_wast ); + set_abi( N(eosio.token), eosio_token_abi ); + produce_blocks(1); + // create currency + auto act = mutable_variant_object() + ("issuer", "eosio") + ("maximum_supply", eosio::chain::asset::from_string("1000000000.0000 SYS")); + push_action(N(eosio.token), N(create), N(eosio.token), act ); + + // issue + for (account_name a: accs) { + push_action( N(eosio.token), N(issue), "eosio", mutable_variant_object() + ("to", name(a) ) + ("quantity", eosio::chain::asset::from_string("10000.0000 SYS") ) + ("memo", "") + ); + } + produce_blocks(1); + + // create currency 2 + act = mutable_variant_object() + ("issuer", "eosio") + ("maximum_supply", eosio::chain::asset::from_string("1000000000.0000 AAA")); + push_action(N(eosio.token), N(create), N(eosio.token), act ); + // issue + for (account_name a: accs) { + push_action( N(eosio.token), N(issue), "eosio", mutable_variant_object() + ("to", name(a) ) + ("quantity", eosio::chain::asset::from_string("9999.0000 AAA") ) + ("memo", "") + ); + } + produce_blocks(1); + + // create currency 3 + act = mutable_variant_object() + ("issuer", "eosio") + ("maximum_supply", eosio::chain::asset::from_string("1000000000.0000 CCC")); + push_action(N(eosio.token), N(create), N(eosio.token), act ); + // issue + for (account_name a: accs) { + push_action( N(eosio.token), N(issue), "eosio", mutable_variant_object() + ("to", name(a) ) + ("quantity", eosio::chain::asset::from_string("7777.0000 CCC") ) + ("memo", "") + ); + } + produce_blocks(1); + + // create currency 3 + act = mutable_variant_object() + ("issuer", "eosio") + ("maximum_supply", eosio::chain::asset::from_string("1000000000.0000 BBB")); + push_action(N(eosio.token), N(create), N(eosio.token), act ); + // issue + for (account_name a: accs) { + push_action( N(eosio.token), N(issue), "eosio", mutable_variant_object() + ("to", name(a) ) + ("quantity", eosio::chain::asset::from_string("8888.0000 BBB") ) + ("memo", "") + ); + } + produce_blocks(1); + + // get table: normal case + eosio::chain_apis::read_only plugin(*(this->control), fc::microseconds(INT_MAX)); + eosio::chain_apis::read_only::get_table_rows_params p; + p.code = N(eosio.token); + p.scope = "inita"; + p.table = N(accounts); + p.json = true; + p.index_position = "primary"; + eosio::chain_apis::read_only::get_table_rows_result result = plugin.read_only::get_table_rows(p); + BOOST_REQUIRE_EQUAL(4, result.rows.size()); + BOOST_REQUIRE_EQUAL(false, result.more); + if (result.rows.size() >= 4) { + BOOST_REQUIRE_EQUAL("9999.0000 AAA", result.rows[0]["balance"].as_string()); + BOOST_REQUIRE_EQUAL("8888.0000 BBB", result.rows[1]["balance"].as_string()); + BOOST_REQUIRE_EQUAL("7777.0000 CCC", result.rows[2]["balance"].as_string()); + BOOST_REQUIRE_EQUAL("10000.0000 SYS", result.rows[3]["balance"].as_string()); + } + + // get table: reverse ordered + p.reverse = true; + result = plugin.read_only::get_table_rows(p); + BOOST_REQUIRE_EQUAL(4, result.rows.size()); + BOOST_REQUIRE_EQUAL(false, result.more); + if (result.rows.size() >= 4) { + BOOST_REQUIRE_EQUAL("9999.0000 AAA", result.rows[3]["balance"].as_string()); + BOOST_REQUIRE_EQUAL("8888.0000 BBB", result.rows[2]["balance"].as_string()); + BOOST_REQUIRE_EQUAL("7777.0000 CCC", result.rows[1]["balance"].as_string()); + BOOST_REQUIRE_EQUAL("10000.0000 SYS", result.rows[0]["balance"].as_string()); + } + + // get table: reverse ordered, with ram payer + p.reverse = true; + p.show_payer = true; + result = plugin.read_only::get_table_rows(p); + BOOST_REQUIRE_EQUAL(4, result.rows.size()); + BOOST_REQUIRE_EQUAL(false, result.more); + if (result.rows.size() >= 4) { + BOOST_REQUIRE_EQUAL("9999.0000 AAA", result.rows[3]["data"]["balance"].as_string()); + BOOST_REQUIRE_EQUAL("8888.0000 BBB", result.rows[2]["data"]["balance"].as_string()); + BOOST_REQUIRE_EQUAL("7777.0000 CCC", result.rows[1]["data"]["balance"].as_string()); + BOOST_REQUIRE_EQUAL("10000.0000 SYS", result.rows[0]["data"]["balance"].as_string()); + BOOST_REQUIRE_EQUAL("eosio", result.rows[0]["payer"].as_string()); + BOOST_REQUIRE_EQUAL("eosio", result.rows[1]["payer"].as_string()); + BOOST_REQUIRE_EQUAL("eosio", result.rows[2]["payer"].as_string()); + BOOST_REQUIRE_EQUAL("eosio", result.rows[3]["payer"].as_string()); + } + p.show_payer = false; + + // get table: normal case, with bound + p.lower_bound = "BBB"; + p.upper_bound = "CCC"; + p.reverse = false; + result = plugin.read_only::get_table_rows(p); + BOOST_REQUIRE_EQUAL(2, result.rows.size()); + BOOST_REQUIRE_EQUAL(false, result.more); + if (result.rows.size() >= 2) { + BOOST_REQUIRE_EQUAL("8888.0000 BBB", result.rows[0]["balance"].as_string()); + BOOST_REQUIRE_EQUAL("7777.0000 CCC", result.rows[1]["balance"].as_string()); + } + + // get table: reverse case, with bound + p.lower_bound = "BBB"; + p.upper_bound = "CCC"; + p.reverse = true; + result = plugin.read_only::get_table_rows(p); + BOOST_REQUIRE_EQUAL(2, result.rows.size()); + BOOST_REQUIRE_EQUAL(false, result.more); + if (result.rows.size() >= 2) { + BOOST_REQUIRE_EQUAL("8888.0000 BBB", result.rows[1]["balance"].as_string()); + BOOST_REQUIRE_EQUAL("7777.0000 CCC", result.rows[0]["balance"].as_string()); + } + + // get table: normal case, with limit + p.lower_bound = p.upper_bound = ""; + p.limit = 1; + p.reverse = false; + result = plugin.read_only::get_table_rows(p); + BOOST_REQUIRE_EQUAL(1, result.rows.size()); + BOOST_REQUIRE_EQUAL(true, result.more); + if (result.rows.size() >= 1) { + BOOST_REQUIRE_EQUAL("9999.0000 AAA", result.rows[0]["balance"].as_string()); + } + + // get table: reverse case, with limit + p.lower_bound = p.upper_bound = ""; + p.limit = 1; + p.reverse = true; + result = plugin.read_only::get_table_rows(p); + BOOST_REQUIRE_EQUAL(1, result.rows.size()); + BOOST_REQUIRE_EQUAL(true, result.more); + if (result.rows.size() >= 1) { + BOOST_REQUIRE_EQUAL("10000.0000 SYS", result.rows[0]["balance"].as_string()); + } + + // get table: normal case, with bound & limit + p.lower_bound = "BBB"; + p.upper_bound = "CCC"; + p.limit = 1; + p.reverse = false; + result = plugin.read_only::get_table_rows(p); + BOOST_REQUIRE_EQUAL(1, result.rows.size()); + BOOST_REQUIRE_EQUAL(true, result.more); + if (result.rows.size() >= 1) { + BOOST_REQUIRE_EQUAL("8888.0000 BBB", result.rows[0]["balance"].as_string()); + } + + // get table: reverse case, with bound & limit + p.lower_bound = "BBB"; + p.upper_bound = "CCC"; + p.limit = 1; + p.reverse = true; + result = plugin.read_only::get_table_rows(p); + BOOST_REQUIRE_EQUAL(1, result.rows.size()); + BOOST_REQUIRE_EQUAL(true, result.more); + if (result.rows.size() >= 1) { + BOOST_REQUIRE_EQUAL("7777.0000 CCC", result.rows[0]["balance"].as_string()); + } + +} FC_LOG_AND_RETHROW() + +BOOST_FIXTURE_TEST_CASE( get_table_by_seckey_test, TESTER ) try { + produce_blocks(2); + + create_accounts({ N(eosio.token), N(eosio.ram), N(eosio.ramfee), N(eosio.stake), + N(eosio.bpay), N(eosio.vpay), N(eosio.saving), N(eosio.names) }); + + std::vector accs{N(inita), N(initb), N(initc), N(initd)}; + create_accounts(accs); + produce_block(); + + set_code( N(eosio.token), eosio_token_wast ); + set_abi( N(eosio.token), eosio_token_abi ); + produce_blocks(1); + + // create currency + auto act = mutable_variant_object() + ("issuer", "eosio") + ("maximum_supply", eosio::chain::asset::from_string("1000000000.0000 SYS")); + push_action(N(eosio.token), N(create), N(eosio.token), act ); + + // issue + for (account_name a: accs) { + push_action( N(eosio.token), N(issue), "eosio", mutable_variant_object() + ("to", name(a) ) + ("quantity", eosio::chain::asset::from_string("10000.0000 SYS") ) + ("memo", "") + ); + } + produce_blocks(1); + + set_code( config::system_account_name, eosio_system_wast ); + set_abi( config::system_account_name, eosio_system_abi ); + + // bidname + auto bidname = [this]( const account_name& bidder, const account_name& newname, const asset& bid ) { + return push_action( N(eosio), N(bidname), bidder, fc::mutable_variant_object() + ("bidder", bidder) + ("newname", newname) + ("bid", bid) + ); + }; + + bidname(N(inita), N(com), eosio::chain::asset::from_string("10.0000 SYS")); + bidname(N(initb), N(org), eosio::chain::asset::from_string("11.0000 SYS")); + bidname(N(initc), N(io), eosio::chain::asset::from_string("12.0000 SYS")); + bidname(N(initd), N(html), eosio::chain::asset::from_string("14.0000 SYS")); + produce_blocks(1); + + // get table: normal case + eosio::chain_apis::read_only plugin(*(this->control), fc::microseconds(INT_MAX)); + eosio::chain_apis::read_only::get_table_rows_params p; + p.code = N(eosio); + p.scope = "eosio"; + p.table = N(namebids); + p.json = true; + p.index_position = "secondary"; // ordered by high_bid + p.key_type = "i64"; + eosio::chain_apis::read_only::get_table_rows_result result = plugin.read_only::get_table_rows(p); + BOOST_REQUIRE_EQUAL(4, result.rows.size()); + BOOST_REQUIRE_EQUAL(false, result.more); + if (result.rows.size() >= 4) { + BOOST_REQUIRE_EQUAL("html", result.rows[0]["newname"].as_string()); + BOOST_REQUIRE_EQUAL("initd", result.rows[0]["high_bidder"].as_string()); + BOOST_REQUIRE_EQUAL("140000", result.rows[0]["high_bid"].as_string()); + + BOOST_REQUIRE_EQUAL("io", result.rows[1]["newname"].as_string()); + BOOST_REQUIRE_EQUAL("initc", result.rows[1]["high_bidder"].as_string()); + BOOST_REQUIRE_EQUAL("120000", result.rows[1]["high_bid"].as_string()); + + BOOST_REQUIRE_EQUAL("org", result.rows[2]["newname"].as_string()); + BOOST_REQUIRE_EQUAL("initb", result.rows[2]["high_bidder"].as_string()); + BOOST_REQUIRE_EQUAL("110000", result.rows[2]["high_bid"].as_string()); + + BOOST_REQUIRE_EQUAL("com", result.rows[3]["newname"].as_string()); + BOOST_REQUIRE_EQUAL("inita", result.rows[3]["high_bidder"].as_string()); + BOOST_REQUIRE_EQUAL("100000", result.rows[3]["high_bid"].as_string()); + } + + // reverse search, with show ram payer + p.reverse = true; + p.show_payer = true; + result = plugin.read_only::get_table_rows(p); + BOOST_REQUIRE_EQUAL(4, result.rows.size()); + BOOST_REQUIRE_EQUAL(false, result.more); + if (result.rows.size() >= 4) { + BOOST_REQUIRE_EQUAL("html", result.rows[3]["data"]["newname"].as_string()); + BOOST_REQUIRE_EQUAL("initd", result.rows[3]["data"]["high_bidder"].as_string()); + BOOST_REQUIRE_EQUAL("140000", result.rows[3]["data"]["high_bid"].as_string()); + BOOST_REQUIRE_EQUAL("initd", result.rows[3]["payer"].as_string()); + + BOOST_REQUIRE_EQUAL("io", result.rows[2]["data"]["newname"].as_string()); + BOOST_REQUIRE_EQUAL("initc", result.rows[2]["data"]["high_bidder"].as_string()); + BOOST_REQUIRE_EQUAL("120000", result.rows[2]["data"]["high_bid"].as_string()); + BOOST_REQUIRE_EQUAL("initc", result.rows[2]["payer"].as_string()); + + BOOST_REQUIRE_EQUAL("org", result.rows[1]["data"]["newname"].as_string()); + BOOST_REQUIRE_EQUAL("initb", result.rows[1]["data"]["high_bidder"].as_string()); + BOOST_REQUIRE_EQUAL("110000", result.rows[1]["data"]["high_bid"].as_string()); + BOOST_REQUIRE_EQUAL("initb", result.rows[1]["payer"].as_string()); + + BOOST_REQUIRE_EQUAL("com", result.rows[0]["data"]["newname"].as_string()); + BOOST_REQUIRE_EQUAL("inita", result.rows[0]["data"]["high_bidder"].as_string()); + BOOST_REQUIRE_EQUAL("100000", result.rows[0]["data"]["high_bid"].as_string()); + BOOST_REQUIRE_EQUAL("inita", result.rows[0]["payer"].as_string()); + } + + // limit to 1 (get the highest bidname) + p.reverse = false; + p.show_payer = false; + p.limit = 1; + result = plugin.read_only::get_table_rows(p); + BOOST_REQUIRE_EQUAL(1, result.rows.size()); + BOOST_REQUIRE_EQUAL(true, result.more); + if (result.rows.size() >= 1) { + BOOST_REQUIRE_EQUAL("html", result.rows[0]["newname"].as_string()); + BOOST_REQUIRE_EQUAL("initd", result.rows[0]["high_bidder"].as_string()); + BOOST_REQUIRE_EQUAL("140000", result.rows[0]["high_bid"].as_string()); + } + + // limit to 1 reverse, (get the lowest bidname) + p.reverse = true; + p.show_payer = false; + p.limit = 1; + result = plugin.read_only::get_table_rows(p); + BOOST_REQUIRE_EQUAL(1, result.rows.size()); + BOOST_REQUIRE_EQUAL(true, result.more); + if (result.rows.size() >= 1) { + BOOST_REQUIRE_EQUAL("com", result.rows[0]["newname"].as_string()); + BOOST_REQUIRE_EQUAL("inita", result.rows[0]["high_bidder"].as_string()); + BOOST_REQUIRE_EQUAL("100000", result.rows[0]["high_bid"].as_string()); + } + +} FC_LOG_AND_RETHROW() + +BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/launcher_test.py b/tests/launcher_test.py index 9179a69b58dfe0ef255bbe6cf5348e51d5864de8..b7d21b4117928d65c2ac43f2a4ab2386e4f03b46 100755 --- a/tests/launcher_test.py +++ b/tests/launcher_test.py @@ -52,7 +52,8 @@ try: cluster.killall(allInstances=killAll) cluster.cleanup() Print("Stand up cluster") - if cluster.launch(pnodes=4, p2pPlugin=p2pPlugin) is False: + pnodes=4 + if cluster.launch(pnodes=pnodes, totalNodes=pnodes, p2pPlugin=p2pPlugin) is False: cmdError("launcher") errorExit("Failed to stand up eos cluster.") else: diff --git a/tests/nodeos_forked_chain_test.py b/tests/nodeos_forked_chain_test.py index 01115285a6e7897c01df0601df8dac04f37cfef7..1ef2079e87801d41fa593bf403764dc48771320f 100755 --- a/tests/nodeos_forked_chain_test.py +++ b/tests/nodeos_forked_chain_test.py @@ -30,7 +30,12 @@ def analyzeBPs(bps0, bps1, expectDivergence): length=len(bps0) firstDivergence=None errorInDivergence=False + analysysPass=0 + bpsStr=None + bpsStr0=None + bpsStr1=None while start < length: + analysysPass+=1 bpsStr=None for i in range(start,length): bp0=bps0[i] diff --git a/tests/nodeos_run_remote_test.py b/tests/nodeos_run_remote_test.py index 6c918f71c64c4bc3f8d7c68ff19f87277fbbf667..21e15bb9c723aa3978488896c39d35717b62aeae 100755 --- a/tests/nodeos_run_remote_test.py +++ b/tests/nodeos_run_remote_test.py @@ -43,7 +43,7 @@ try: (pnodes, total_nodes-pnodes, topo, delay)) Print("Stand up cluster") - if cluster.launch(pnodes=pnodes, totalNodes=total_nodes, prodCount=prodCount, topo=topo, delay=delay, onlyBios=onlyBios, dontKill=dontKill) is False: + if cluster.launch(pnodes=pnodes, totalNodes=total_nodes, prodCount=prodCount, topo=topo, delay=delay, onlyBios=onlyBios) is False: errorExit("Failed to stand up eos cluster.") Print ("Wait for Cluster stabilization") diff --git a/tests/nodeos_run_test.py b/tests/nodeos_run_test.py index 37b46613aaf9becb081ce745d17b3f759eefc44c..4196eb58a2beceb4adc3da03e5f607a488155680 100755 --- a/tests/nodeos_run_test.py +++ b/tests/nodeos_run_test.py @@ -42,7 +42,7 @@ walletPort=args.wallet_port Utils.Debug=debug localTest=True if server == TestHelper.LOCAL_HOST else False -cluster=Cluster(walletd=True, enableMongo=enableMongo, defproduceraPrvtKey=defproduceraPrvtKey, defproducerbPrvtKey=defproducerbPrvtKey) +cluster=Cluster(host=server, port=port, walletd=True, enableMongo=enableMongo, defproduceraPrvtKey=defproduceraPrvtKey, defproducerbPrvtKey=defproducerbPrvtKey) walletMgr=WalletMgr(True, port=walletPort) testSuccessful=False killEosInstances=not dontKill diff --git a/tests/p2p_tests/fuzz_test_generic.sh b/tests/p2p_tests/fuzz_test_generic.sh deleted file mode 100644 index ae913565c867c388695b1b033c2de5bb445a6520..0000000000000000000000000000000000000000 --- a/tests/p2p_tests/fuzz_test_generic.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env bash -# -# This script captures the generic fuzz testing to which -# net_plugin has been subjected. It typically results in -# message buffers in excess of 1 gigabyte. -# -if ! pgrep nodeos > /dev/null; then - echo "Run nodeos with net_plugin configured for port 9876." - exit 1 -fi -for i in `seq 1 10000`; do netcat localhost 9876 < /dev/urandom; done diff --git a/tests/p2p_tests/pump/run_test.pl b/tests/p2p_tests/pump/run_test.pl deleted file mode 100755 index 11e467a5d2ea96fe17916d0e8bfb41b80d8d42ad..0000000000000000000000000000000000000000 --- a/tests/p2p_tests/pump/run_test.pl +++ /dev/null @@ -1,285 +0,0 @@ -#!/usr/bin/perl - -use strict; -use Getopt::Long; -use Env; -use File::Basename; -use File::copy; -use File::Spec; -use File::Path; -use Cwd; - -my $eos_home = defined $ENV{EOS_HOME} ? $ENV{EOS_HOME} : getcwd; -my $eosd = $eos_home . "/programs/eosd/eosd"; -my $eosc = $eos_home . "/programs/eosc/eosc"; - -my $nodes = defined $ENV{EOS_TEST_RING} ? $ENV{EOS_TEST_RING} : "1"; -my $pnodes = defined $ENV{EOS_TEST_PRODUCERS} ? $ENV{EOS_TEST_PRODUCERS} : "1"; - -my $prods = 21; -my $genesis = "$eos_home/genesis.json"; -my $http_port_base = 8888; -my $p2p_port_base = 9876; -my $data_dir_base = "tdn"; -my $hostname = "127.0.0.1"; -my $first_pause = 0; -my $launch_pause = 0; -my $run_duration = 60; -my $topo = "ring"; -my $override_gts = ""; -my $no_delay=0; -my $test=1; - -if (!GetOptions("nodes=i" => \$nodes, - "first-pause=i" => \$first_pause, - "launch-pause=i" => \$launch_pause, - "duration=i" => \$run_duration, - "topo=s" => \$topo, - "test=i" => \$test, - "time-stamp=s" => \$override_gts, - "pnodes=i" => \$pnodes)) { - print "usage: $ARGV[0] [--nodes=] [--pnodes=] [--topo=] [--first-pause=] [--launch-pause=] [--duration=] [--time-stamp=